下記の様なクラスがあった場合、javaならではの(?)スマートな書き方ってあるのでしょうか。
funcPre関数の重複を簡略化できるのかなと言う質問になります。
class Sample{ public void funcA(int n){ funcPre(); //処理 } public void funcB(int n){ funcPre(); //処理 } public void funcC(int n, int m){ funcPre(); //処理 } public void funcD(int n){ //処理 } //前処理 private void funcPre(){ //処理 } }
追記
多くのご回答有難うございました。
勉強になります。
記述が重複する部分をprivate関数に置き換えていると、今度は関連性のないprivate関数が増えていって、その部分が読みにくくなると思って、質問させて頂きました。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/20 07:11
2017/09/20 15:47
回答5件
0
もっとコードが具体的になれば違った回答もあるかもしれませんが、質問文にあるコードで十分簡潔だと考えてよいです。
記述が重複する部分をprivate関数に置き換えていると、今度は関連性のないprivate関数が増えていって、その部分が読みにくくなると思って、質問させて頂きました。
private メソッドが互いに関連性がない(=独立している)方がよりよいコードと言えます。
public メソッドから利用する場合に private メソッドの呼び出し順やフィールドの状態に注意しなければならないとすると、より悪い状況におちいっています。
private メソッドが単純に多い場合は別のクラス(=責務)へと切り出せないか検討するとよいでしょう。
投稿2017/09/20 11:26
総合スコア936
0
Java
1public abstract class Sample { 2 3 private void preFunc(){ 4 //処理 5 } 6 7 protected abstract void func(); 8 9 public void do() { 10 preFunc(); 11 func(); 12 } 13} 14 15class SampleA extends Sample { 16 private int n; 17 18 public SampleA(int n) { 19 this.n = n; 20 } 21 22 @Override 23 protected void func() { 24 //処理 25 } 26} 27 28class SampleB extends Sample { 29 private int n; 30 31 public SampleB(int n) { 32 this.n = n; 33 } 34 35 @Override 36 protected void func() { 37 //処理 38 } 39} 40 41class SampleC extends Sample { 42 private int n; 43 private int m; 44 45 public SampleC(int n, int m) { 46 this.n = n; 47 this.m = m; 48 } 49 50 @Override 51 protected void func() { 52 //処理 53 } 54} 55 56class SampleD extends Sample { 57 private int n; 58 59 public SampleD(int n) { 60 this.n = n; 61 } 62 63 @Override 64 protected void func() { 65 //処理 66 } 67 68 @Override 69 public void do() { 70 func(); 71 } 72} 73 74public class Main { 75 public static void main(String[] args) { 76 Sample sampleA = new SampleA(1); 77 sampleA.do(); 78 79 Sample sampleB = new SampleB(1); 80 sampleB.do(); 81 82 Sample sampleC = new SampleC(1,2); 83 sampleC.do(); 84 85 Sample sampleD = new SampleD(1); 86 sampleD.do(); 87 } 88}
す、すまーと
投稿2017/09/20 06:38
総合スコア1280
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
目的に沿ったものではないかもしれませんがコンストラクタで呼ぶのはどうでしょうか。
Java
1class Sample{ 2 3 public Sample(){ 4 funcPre(); 5 } 6 7 public void funcA(int n){ 8 //処理 9 } 10 11 public void funcB(int n){ 12 //処理 13 } 14 15 public void funcC(int n, int m){ 16 //処理 17 } 18 19 public void funcD(int n){ 20 //処理 21 } 22 23 //前処理 24 private void funcPre(){ 25 //処理 26 } 27}
funcD()を使う場合にもfuncPre()が呼び出されてしまうという点が許容できるのであれば ですが。。。
投稿2017/09/20 06:10
総合スコア883
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
よくわかりませんが、たとえばこういうのですか (未検証)。
java
1class Sample { 2 class Action { 3 public void exec() { 4 funcPre(); 5 doExec(); 6 } 7 protected void funcPre(){ 8 //処理 9 } 10 abstract public void doExec(); 11 12 } 13 class ActionA extends Action { 14 public void doExec() { 15 // 処理 16 }; 17 public setArgs(int n) { 18 this.n = n; 19 return this; 20 } 21 } 22 23 public void funcA(int n){ 24 return new ActionA().setArgs(n).exec(); 25 } 26 27 public void funcB(int n){ 28 return new ActionB().setArgs(n).exec(); 29 } 30 31 public void funcC(int n, int m){ 32 return new ActionC().setArgs(n, m).exec(); 33 } 34 35 public void funcD(int n){ 36 //処理 37 } 38}
投稿2017/09/20 06:10
総合スコア2468
0
ベストアンサー
Javaならでは…
Javaの標準機能だけでは無理なのですが、スマートな書き方であれば、AspectJ5によるアノテーション記法でしょうか。
以下のサンプルコードを動かすにはaspectjrtとaspectjweaverのライブラリが必要なので、少し難しいです。
Java
1import org.aspectj.lang.JoinPoint; 2import org.aspectj.lang.annotation.Aspect; 3import org.aspectj.lang.annotation.Before; 4 5// @Aspectを書いたクラスはAspectJのコンパイル対象クラスとなり、@Beforeなどが使えるようになる 6@Aspect 7public class Sample { 8 9 public void funcA(int n) { 10 //処理 11 System.out.println("funcA " + n); 12 } 13 14 public void funcB(int n) { 15 //処理 16 System.out.println("funcB " + n); 17 } 18 19 public void funcC(int n, int m) { 20 //処理 21 System.out.println("funcC " + n + " " + m); 22 } 23 24 public void funcD(int n) { 25 //処理 26 System.out.println("funcD " + n); 27 } 28 29 // @Beforeの中に条件を書くと、条件に当てはまるメソッドの処理の前に呼び出してくれる 30 // callは「そのメソッドを呼び出したとき」という条件 31 // 条件の書き方はAspectJの仕様を参照してください 32 // 以下の条件の場合、funcA、またはfuncB、またはfuncCのときだけ実行される 33 @Before("call(void funcA(int))" 34 + " || call(void funcB(int))" 35 + " || call(void funcC(int, int))") 36 public void funcPre(JoinPoint joinPoint) { 37 // JoinPointは呼び出し元などの情報が入っている 38 39 System.out.println("funcPre"); 40 // このメソッド内でthisと書いても、funcAを呼んでいるインスタンスとは別物なので注意 41 // 以下のように呼び出し元インスタンスはgetTargetで得る 42 // Sample sample = (Sample) joinPoint.getTarget(); 43 } 44 45 public static void main(String[] args) { 46 Sample m = new Sample(); 47 m.funcA(0); 48 m.funcB(1); 49 m.funcC(2, 3); 50 m.funcD(4); 51 } 52} 53
Mavenを使えばAspectJを使ったコードを簡単にビルドできます。mavenを利用した場合のpom.xmlの参考です。
XML
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>example</groupId> 5 <artifactId>aspectj</artifactId> 6 <version>1.0-SNAPSHOT</version> 7 <packaging>jar</packaging> 8 <properties> 9 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 10 <maven.compiler.source>1.8</maven.compiler.source> 11 <maven.compiler.target>1.8</maven.compiler.target> 12 13 <aspectj-maven-plugin.version>1.10</aspectj-maven-plugin.version> 14 <aspectj.version>1.8.10</aspectj.version> 15 </properties> 16 17 18 <build> 19 <plugins> 20 <plugin> 21 <artifactId>maven-compiler-plugin</artifactId> 22 <version>2.5.1</version> 23 <configuration> 24 <source>${maven.compiler.source}</source> 25 <target>${maven.compiler.target}</target> 26 </configuration> 27 </plugin> 28 <plugin> 29 <groupId>org.codehaus.mojo</groupId> 30 <artifactId>aspectj-maven-plugin</artifactId> 31 <version>${aspectj-maven-plugin.version}</version> 32 <configuration> 33 <complianceLevel>${maven.compiler.source}</complianceLevel> 34 <source>${maven.compiler.source}</source> 35 <target>${maven.compiler.target}</target> 36 </configuration> 37 <executions> 38 <execution> 39 <phase>process-sources</phase> 40 <goals> 41 <goal>compile</goal> 42 </goals> 43 </execution> 44 </executions> 45 </plugin> 46 </plugins> 47 </build> 48 49 <dependencies> 50 <dependency> 51 <groupId>org.aspectj</groupId> 52 <artifactId>aspectjrt</artifactId> 53 <version>${aspectj.version}</version> 54 </dependency> 55 56 <dependency> 57 <groupId>org.aspectj</groupId> 58 <artifactId>aspectjweaver</artifactId> 59 <version>${aspectj.version}</version> 60 </dependency> 61 </dependencies> 62 63</project>
投稿2017/09/20 08:44
編集2017/09/20 09:10総合スコア9206
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/21 04:53
2017/09/21 05:19
2017/09/21 05:30
2017/09/21 05:33
2017/09/21 06:15
2017/09/21 06:17
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。