3

私の質問は、OOP のクラス設計に関するものです。Canceled、Modified、Added クラスの親クラスである ItemBase があるとします。Provider と Distributor の親である DueToBase クラスもあります。


簡単な図


ItemBase は DueToBase クラスにより変更される場合があります。

ItemBase には DueToBase 型のプロパティがあり、DueToBase には compute() というインターフェイス メソッドがあるとします。計算アルゴリズムは、特定の ItemBase 派生クラスに関連していますしたがって、ItemBase と DueToBase の関係には 6 つの異なる組み合わせがあります。

例。

ItemBase ib = new Added();
ib.changed = new Provider(ib);
ib.changed.compute();

私の質問は、ItemBase と DueToBase の関係を実際のオブジェクト指向プログラミングでどのように構築する必要があるかということです。インスタンス ItemBase のタイプを確認するための compute メソッドに、swich/case または if 条件句がありません。DueToBase の内部に別の XXXBase クラスがあり、そのクラスに別のインターフェイス メソッド YYY() があり、そのアルゴリズムが DueToBase の特定のインスタンス (さらには ItemBase) に依存している場合は、さらに悪化します。このような場合はどのように対処すればよいですか?そのようなことのための良いプログラミングパターンはありますか? たどった方向が悪いのかもしれません。どうぞよろしくお願いいたします。

私の図が明確ではなかったのかもしれません。問題は次の...疑似コードにあります:

doSomething(){
   if(itemBase instanceof Cancelled){
      if(dueToBase instanceof Provider)
         algorithm1();
      else if(dueToBase instanceof Company)
         algorithm2();
   }else if(itemBase instanceof Modified){
      if(dueToBase instanceof Provider)
         algorithm3();
      else if(dueToBase instanceof Company)
         algorithm4();
   }else if(itemBase instanceof Added){
      if(dueToBase instanceof Provider)
         algorithm5();
      else if(dueToBase instanceof Company)
         algorithm6();
   }
}

if 句が深くなると、さらに悪化します。

4

4 に答える 4

4

クラスはメソッドを含む抽象ItemBaseクラスにすることができcompute()、すべての子クラスは独自の実装を持つことができます。

後でこのようなことをすることができます、

ItemBase ib = new Added();
ib.changed = new Provider(ib);
ib.changed.compute();

ここで、でcomputeメソッドを呼び出すと、クラスib.changedのコンピューティング実装が実行されます。Added


Providerあなたの場合、基本クラスのために、とを区別するインスタンス変数を追加しますCompanyboolean旗や。のようなものint

次に、使用する代わりに、dueToBase instanceof Providerifステートメントを作成できます。したがって、更新された擬似コードは数行に減少します。このようなもの、

doSomething(){
      if(dueToBase.isProvider) {
         algorithm1(); //execute if Provider
      } else { 
         algorithm2(); //execute if Company
      }
}

これで、コンピューティングを選択する複雑さが抽象パターンによって処理されるようになり、それが会社であるかプロバイダーであるかを心配するだけで済みます。

于 2012-07-18T23:45:41.217 に答える
1

戦略パターンと言えば

abstract class ItemBase {
  public DueToBase myDueToBase;
  public void partOfTheAlgorithmThatOnlySpecificIBKnows();
}

class Modified extends ItemBase {
  public void partOfTheAlgorithmThatOnlySpecificIBKnows() {
     //stuff only Modified knows
  }
}


abstract class DueToBase {
    public void partOfTheAlgorithmThatOnlySpecificDTBKnows();
}

class Provider extends DueToBase {
 //relevant code
  public ItemBase myItemBase;
  public void partOfTheAlgorithmThatOnlySpecificDTBKnows(){
       //stuff only provider knows
  }

  public void compute() {
       //you can also pass this but pointless since you all ready have the reference
       myItemBase.partOfTheAlgorithmThatOnlySpecificIBKnows();
       //some more code
  }
}

ItemBase ib = new Added();
ib.changed = new Provider(ib);
ib.changed.compute();

この例では、次のように呼び出します。

1. compute on Provider
2. part of the algorithm that Modified knows how to calculate
3. rest of the code for the algorithm

関数にcomputeは、継承されたクラスに必要なすべての特定のメソッドがあり、compute()関数のアルゴリズムを変えることができます。

これで問題が解決しない場合は、Owl が言ったように、要件を見て新しい設計を考え出す必要があるかもしれません。


また、ifs はありませんが、ifs と同じことを行う方法が他にもあります。継承メカニズムに任せているだけです。

于 2012-07-19T00:37:12.203 に答える