質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

282閲覧

一連の流れが同じだが定数やインスタンスが異なる連続処理

lupus_dingo

総合スコア257

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2019/04/28 07:01

編集2019/04/28 07:13

例えば、
db取得、取得結果の編集、ファイル出力、dbステータス更新
という一連の流れがあるとします。

この一連の流れはほとんど同じで、処理内で使用される定数やインスタンスが区分によって異なる処理を複数回行う場合、メイン処理で条件分岐を行わずに実装するなら、皆さんならどう実装しますか?

私が思い付いたのは全て一つのenumで持つということですが、実装していくとちょっと複雑になってしまいました。以下以外にもっとスマートにする方法はあるでしょうか?

java

1enum Kubun{ 2K1 ( 3 "あかさ1","たなは1","まやら1" 4), 5K2( 6 "あかさ2","たなは2","まやら2" 7), 8K3(/*省略*/); 9 10private String code1; 11private String code2; 12private String code3; 13 14// 結局ここで条件分岐必要 15public BeanInterface getInstance(){ 16 if(this = K1){return new K1bean();} 17 if(this = K2){return new K2bean();} 18 else {return new K3bean();} 19} 20} 21

java

1public void mainProcess(){ 2 for(Kubun kubun :Kubun.values()){ 3 List<Result> results = getDB(kubun); 4 Beaninterface bean=kubun.getinstance(); 5 //convertの中では条件分岐せずにgetCode1()等を呼び出す 6 Beaninterface outData = kubun.convert(results,bean); 7 outputfile(outData); 8 updatestatus(outData); 9 } 10}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

enumでもクラス同様、オーバーライド出来ます。

java

1enum Kubun{ 2 // 分岐するものについてはそれぞれオーバーライド 3 K1("あかさ1","たなは1","まやら1"){ 4 @Override 5 public BeanInterface getInstance(){ 6 return new K1bean(); 7 } 8 }, 9 K2("あかさ2","たなは2","まやら2"){ 10 @Override 11 public BeanInterface getInstance(){ 12 return new K2bean(); 13 } 14 }, 15 K3(/*省略*/); 16 17 private String code1; 18 private String code2; 19 private String code3; 20 21 // 共通処理を書く 22 public BeanInterface getInstance(){ 23 return new K3bean(); 24 } 25}

Java8以降なら、例えばこのgetInstance()メソッドであれば、Supplierインタフェースで代用することもできるかと思います。

java

1enum Kubun{ 2 K1(Arrays.asList("あかさ1","たなは1","まやら1"), K1bean::new), 3 K2(Arrays.asList("あかさ2","たなは2","まやら2"), K2bean::new), 4 K3(Arrays.asList("あかさ3","たなは3","まやら3"), K3bean::new); 5// もしくは共通する部分に関してはnullにして、メソッドの方でnullか否かで判定するという手もある。 6// K3(Arrays.asList("あかさ3","たなは3","まやら3"), null); 7 8 private List<String> codes; 9 private Supplier<? extends BeanInterface> supplier; 10 11 private Kubun(List<String> codes, Supplier<? extends BeanInterface> supplier) { 12 this.codes = codes; 13 this.supplier = supplier; 14 } 15 16 public BeanInterface getInstance(){ 17 return supplier.get(); 18// K3の第2引数をnullにしている場合 19// return supplier == null ? new K3bean() : supplier.get(); 20 } 21}

投稿2019/04/28 07:23

編集2019/05/02 23:29
swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lupus_dingo

2019/04/29 05:13

なるほど! オンバーライドできるんですね。 今のところこの方法にしようかなと思っていますが、メソッド増えると可読性下がるのが悩みどころですね。 enum使わずに実現できる方法ないかも探ってみます。
lupus_dingo

2019/05/02 23:24

追加回答ありがたいです。 supplier見やすくなりますね! java8なので検討してみます。 回答ありがとうございました。
guest

0

どの程度の違いとか、状況にもよりますが、

単に方法というだけなら、Mapのキーに区分を入れ、値に処理を入れてしまう方法もありますね。

java

1//定義部 2interface Exec 3{ 4 void exec(Object param); 5} 6 7//初期化部 8Map<String , Exec> map = new HashMap<>(); 9map.put(kubun1, new MyExec1()); 10map.put(kubun2, new MyExec2()); 11map.put(kubun3, new MyExec3()); 12 13 14//処理部 15Exec exec = map.get(kubun); 16exec.exec(kubun); 17 18 19

投稿2019/04/29 04:42

ngsvx

総合スコア287

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lupus_dingo

2019/04/29 05:00

なるほど、区分ごとにメイン処理自体をわけているんですね。クラスを分ける予定はないのでここまではしない予定ですが参考になりました。
guest

0

関数合成を使わないやりかたで考えます。

条件分岐

条件分岐の代わりに、ファクトリ、ポリモーフィズムを使って疎結合にするのは定石です。ファクトリのかわりにDIもあるでしょう。ファクトリを new を使わずより抽象化したければ、Class.forName().newInstance()を使う方法があります。これにJSONやXMLのパースを組み合わせればプログラミングの楽しみが増します。

定型処理

定型処理は、Template Method パターンを使うと強制可能、かつ見通しが良くなります。ぜひ検討してください。

参考

リファクタリング『switchのかわりにポリモーフィズムをつかう』

投稿2019/04/28 09:57

xebme

総合スコア1081

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lupus_dingo

2019/04/29 05:05

回答ありがとうございます。 ただ、半分も理解できてないのでとりあえずtemplate method、ポリモーフィズム辺りでぐぐってみます。
guest

0

こういうことができるんだけど、こういうことではないってことなのかな?

import java.util.function.Function; public enum Test { TYPE1A("1", "2"), TYPE2A("3"), TYPE3A(), TYPE1B("1", "2", String::valueOf), TYPE2B("3", String::valueOf), TYPE3B(String::valueOf), ; final String code1; final String code2; final Function<String, String> function; private Test(String code1, String code2, Function<String, String> function) { this.code1 = code1; this.code2 = code2; this.function = function; } private Test(String code1, String code2) { this(code1, code2, String::valueOf); } private Test(String code1, Function<String, String> function) { this(code1, "", function); } private Test(String code1) { this(code1, ""); } private Test() { this(""); } private Test(Function<String, String> function) { this("", function); } public String getCode1() { return code1; } public String getCode2() { return code2; } public Function<String, String> getFunction() { return function; } }

投稿2019/04/28 08:50

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lupus_dingo

2019/04/29 05:09

回答ありがとうございます。 そうですねー。こういうことではないですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問