0

私は抽象クラスXと、このクラスを拡張し、それらを呼び出すいくつかのクラスをA持っBていCます。

他のいくつかのクラスYでは、クラスのタイプに依存するいくつかのメソッド呼び出しがあります。if-else ステートメントは次のようになります。

public class Y implements InterfaceY {

    public Y(){
    }

    public String doStuff (X x, Boolean flag) {
    String s = "";
    if (x instanceof A) {
        doStuff((A) x));
    } else if (x instanceof B) {
        doStuff((B) x));
    } else if (x instanceof C) {
        doStuff((C) x, flag); 
    } else {
        throw new Exeption();
    }
    return s;

    private String doStuff(A a) {
        return "";
    }

    private String doStuff(B b) {
        return "";
    }

    private String doStuff(C c, Boolean flag) {
        return "";
    }
}

すべてのメソッドは同じ名前 ( doStuff()) を持っていますが、クラス (および場合によってはフラグ) に応じて、そのメソッドの異なるメソッド実装を呼び出すことに注意してください。もちろん、これは恐ろしく見え、X から拡張されたクラスが増えると非常に複雑になります。

if-else ステートメントの大部分 (またはすべて) を処理する中間インターフェイス (または何か他のもの) を作成する方法はありますか?

4

6 に答える 6

0

アプローチ 1

状態パターンを使用します。ifそれはあなたの問題を処理し、 s とsを排除しますelse

これがJava の例です。

状態パターンは、メソッド呼び出しを、同じインターフェースを実装するが動作が異なるオブジェクトに委任します。

状態パターンの例:

public class StatePatternExample {
    public static void main(String[] args) {
        Girlfriend anna = new Girlfriend();
                            // OUTPUT
        anna.kiss();        // *happy*
        anna.greet();       // Hey, honey!
        anna.provoke();     // :@
        anna.greet();       // Leave me alone!
        anna.kiss();        // ...
        anna.greet();       // Hey, honey!
    }
}

interface GirlfriendInteraction extends GirlfriendMood {
    public void changeMood(GirlfriendMood mood);
}

class Girlfriend implements GirlfriendInteraction {
    private GirlfriendMood mood = new Normal(this);

    public void provoke() {
        mood.provoke();
    }
    public void kiss() {
        mood.kiss();
    }
    public void greet() {
        mood.greet();
    }
    public void changeMood(GirlfriendMood mood) {
        this.mood = mood;
    }
}

interface GirlfriendMood {
    public void provoke();
    public void kiss();
    public void greet();
}

class Angry implements GirlfriendMood {
    private final GirlfriendInteraction context;

    Angry(GirlfriendInteraction context) { // more parameters, flags, etc. possible
        this.context = context;
    }
    public void provoke() {
        System.out.println("I hate you!");
    }
    public void kiss() {
        System.out.println("...");
        context.changeMood(new Normal(context));
    }
    public void greet() {
        System.out.println("Leave me alone!");
    }
}

class Normal implements GirlfriendMood {
    private final GirlfriendInteraction context;

    Normal(GirlfriendInteraction context) {
        this.context = context;
    }

    public void provoke() {
        System.out.println(":@");
        context.changeMood(new Angry(context));
    }

    public void kiss() {
        System.out.println("*happy*");
    }

    public void greet() {
        System.out.println("Hey, honey!");
    }
}

ご覧のとおり、クラスにはとGirlfriendがありません。それはかなりきれいに見えます。ifelse

クラスGirlfriendはあなたに対応し、abstract class XクラスNormalとは、およびに対応します。AngryABC

次に、クラスYはケースをチェックせずに X に直接委譲します。

アプローチ 2

コマンド パターンを使用します。Y次に、コマンド オブジェクトをsdoStuff()メソッドに渡して、それを実行するだけです。

于 2013-09-19T14:48:00.530 に答える
0

インターフェイスを実装しHandlerてから、サポートされているタイプでマップするのはどうですか:

public interface Handler<T extends X>{
     Class<T> supportedClass;

     void doStuff(T value, Object...args);
}


public class Y implements InterfaceY {

       private Map<Class<?>, Handler<?>> handlers;

      public Y(List<Handler<?>> handlers){
          // populate map
      }


      public void process(X value){
           handler.get(value.getClass).doStuff(X, ...);
           // you would have to figure out how to determine when other values are needed
      }
}
于 2013-09-19T14:48:03.217 に答える
0

二重発送はどうですか?

class X {
    public String letYdoStuff(Y y, Boolean flag) {
        return y.doStuff(this, flag);
    }

    public static void main(String [] args) {
        //X x = new A();
        X x = new B();
        Y y = new Y();

        y.doStuff(x, false);
    }

    public X getThis() {
        return this;
    }
}

class A extends X {
    public String letYdoStuff(Y y, Boolean flag) {
        return y.doStuff(this, flag);
    }
}
class B extends X {
    public String letYdoStuff(Y y, Boolean flag) {
        return y.doStuff(this, flag);
    }
}
class C extends X {
    public String letYdoStuff(Y y, Boolean flag) {
        return y.doStuff(this, flag);
    }
}

class Y {
    public Y(){
    }

    public String doStuff (X x, Boolean flag) {
       String s = "";

       return x.letYdoStuff(this, flag);
   }

   public String doStuff(A a, Boolean flag) {
       System.out.println("in A");
       return "";
   }

   public String doStuff(B b, Boolean flag) {
       System.out.println("in B");
       return "";
   }

   public String doStuff(C c, Boolean flag) {
       System.out.println("in C");
       return "";
   }
}
于 2013-09-19T15:02:20.237 に答える