1

私はクラスを持ってAextends Bます。クラスの名前も拡張するものも変更できません。

ただし、 にはメソッドがありAますdoSomething(名前を変更することはできません)。

コンストラクターで送信されたフラグによると、AI can something or something else.

これらすべての制限を考慮して、フラグに従ってdoSomethingでフォークを処理する方法を提案しますか?

ありがとう

4

4 に答える 4

1

詳細情報なし:

public Foo doSomething() {
   if( flag ) {
       return super.doSomething();
   } else {
       return doSomethingElse();
   }
}

戦略パターンを使用することもできますが、数十行のコードが追加され、デザイン パターンを適用したという感覚以外にはほとんどメリットがありません。

メソッド呼び出しで必要な間接化を使用すると、さらに遅くなる可能性があります。

于 2013-10-31T09:16:35.697 に答える
0

B も拡張する別のクラス C を作成し、必要に応じて A の代わりに使用できないのはなぜですか? 可能であれば、通常は、クラス内のストラテジーの構築を条件付きでハードコーディングしたりハードコーディングしたりすることは避けたほうがよいでしょう。

基本クラスに手を加える必要はありません。別の実装で拡張するだけです。

于 2013-10-31T09:26:34.467 に答える
0

Strategyここでパターンを使用する必要があります

public A(boolean flag){
    if(flag == true){
        this.service = new DoSomethingStrategy();
    }else{
        this.service = new DoSomethingElseStrategy();
    }
}

コードが論理的に大きくなる場合は、コンストラクターで Factory を使用することをお勧めします。

public A(boolean flag){
    this.service = DoSomethingFactory.getService(flag);
}

DoSomethingFactory;内のコードをコピーします。

そして最後にあなたのdoSomething方法で

public void doSomething(){
    this.service.doSomething();
}

doSomething の動作は戦略構造にカプセル化されます。

于 2013-10-31T09:16:22.807 に答える
0

私の意見では、次の 2 つのオプションのいずれかを選択できます。

  • フラグと fordoSomethingをフラグに従って 2 つの内部メソッドに使用します。例えば:

    public class A extends B {
        private boolean forkFlag;
    
        public A (boolean forkFlag) {
          this.forkFlag = forkFlag;
        }
    
        public void doSomething() {
    
          if (forkFlag) {
            doSomething1();
          } else {
            doSomething2();
          }
        } 
    
        private void doSomething1()  { ... }
    
        private void doSomething2()  { ... }
    }
    
  • 戦略の実装を作成します。

    public class A extends B {
       private boolean forkFlag;
       private Runnable doSomethingImpl;
    
       public A (boolean forkFlag) {
         if(forkFlag) {
            doSomethingImpl = new DoSomethingImpl1();
         } else {
            doSomethingImpl = new DoSomethingImpl2();
         }
       }
    
       public void doSomething() {
           doSomethingImpl.run();
       }
    }
    
    
    
    public class DoSomethingImpl1 implements Runnable {
     public void run() { ... }
    }
    
    public class DoSomethingImpl2 implements Runnable {
      public void run() { ... }
    }
    

これら 2 つのどちらを選択するかは、ニーズによって異なります。このフォークがマイナーなもので、通常のフローでの使用例にすぎない場合は、最初のオプションを使用します。3 番目のフローが必要になる可能性がある場合は、戦略パターンを使用して、それが提供するデカップリングを楽​​しんでください。

ストラテジーを使用すると、必要な実装をクラスの外部から注入できdoSomething、コンストラクターを変更するだけで実装を完全に認識できなくなります。

public A (Runnable doSomething) {
   this.doSomething = doSomething;
}

インジェクション パターンはおそらく最も洗練されており、実装からコードを完全に切り離します。また、より堅牢にするためにimplements Runnable、独自のより具体的なインターフェイスに変更することもできます。public interface DoSomething

于 2013-10-31T09:15:52.270 に答える