2

私はしばしば、以下のようなコードを書く必要がある状況に陥ります。IFステートメントの洪水なしにこれをきちんと行うためのデザインパターン-

A obj = new A();
B obj2 = new B();

for ( i = 1 ; i < 20  ; i ++ )  {

if( i == 1 ) 
  obj.setField1(obj2.getOption1())
else if ( i == 2 ) 
  obj.setField1(obj2.getOption2())
else if ( i == 3 ) 
  obj.setField1(obj2.getOption3())

And so on.. for 20 times .. 

obj.setField2(obj2.getNonOptionField2());
obj.setField3(obj2.getNonOptionField3())

}

編集 -

ここでのループとの類似点は、データベースでループしていて、各レコードが他のテーブルにさらに20個のレコードを作成することです。20のレコードでは、条件を追加したものを除いて、ほとんどの列は同じです。

ええ、デザインは最高ではありませんが、私には選択肢がありません。

4

4 に答える 4

3

アクションが整数値に条件付けられている場合、 を作成できますMap<Integer,MyAction>。ここで、MyActionはこの特定の目的のために定義したインターフェイスです。の実装をMyActionマップに配置して整数オプションに対応させ、入ってくる値に応じて実行時にアクションを呼び出します。

interface MyAction {
    void setField(A obj, B obj2);
}
...
Map<Integer,MyAction> actionByNumber = new HashMap<Integer,MyAction>();
actionByNumber.put(1, new MyAction() {
    void setField(A obj, B obj2) {
        obj.setField1(obj2.getOption1());
    }
});
actionByNumber.put(2, new MyAction() {
    void setField(A obj, B obj2) {
        obj.setField1(obj2.getOption2());
    }
});
...
A obj = ...
B obj2 = ...
for (int i = 0 ; i != 20 ; i++) {
    MyAction action = actionByNumber.get(i);
    if (action != null) {
       action.setField(obj, obj2);
    }
}
于 2013-03-06T15:45:58.910 に答える
2

代わりにスイッチ ケースを使用してみてください。

たとえば、コードは次のようになります。

for ( i = 1 ; i < 20  ; i ++ )  {
    switch(i){
        case(1): obj.setField1(obj2.getOption1());
                 break;
        case(2): obj.setField1(obj2.getOption2());
                 break;
        case(3): obj.setField1(obj2.getOption3());
                 break;
    }
}
于 2013-03-06T15:48:15.297 に答える
1

1 つのオプションはswitchステートメントです。

別のオプションはobj2、オプションの配列を保持し、インデックスでアクセスすることです。何かのようなもの:

obj.setField1(obj2.options[i]);

人々はこれの O-Oness について議論しますが、アクセサー メソッドでドレスアップすることができます。

于 2013-03-06T15:47:38.263 に答える
0

+1 dasblinkenlight のインターフェイスの使用と、提案されているパターン。if/switch の増加は、多くの場合、OO リファクタリングが適切であることを示すコードの匂いです。新しい MyAction インスタンスをマップに渡すメソッドを追加できます。ifおよびswitchコンストラクトに対するこのアプローチの利点は、次のとおりです。

1 - Open to extension、closed to modified ポリシーを実装します。新しい動作を追加しますか? 増え続ける元のクラスに別の条件を追加する必要はありません。MyAction の新しい実装を作成して渡すだけです。

2 - 動作は、マップのコンテンツを変更することで実行時に変更できます。

正確な要件によっては、actionByNumber を Map にする必要がない場合があります。必要に応じてリストを並べたり、並べ替えたりすることもできます。

于 2013-03-06T17:29:01.350 に答える