0

私は自分のコードから大きなswitch文を取り除こうとしています。私は既存の列挙型に基づいた戦略パターンがいいと思っていました。コンセプトは次のようである:内部列挙型の戦略パターン

public class MyStrategy { 

    public MyStrategy() { 
     Option.Option1.setMethodToExecute(this::action1); 
     Option.Option2.setMethodToExecute(this::action2); 
    } 

    public void executeChoosenMethod(int i) { 
     Option.values()[i].execute(); 
//  instead of 
//  switch(convertItoOption()) { 
//   case Option1:... 
//   case Option2:... 
//  } 
    } 

    private void action1() { 
     System.out.println("action1"); 
    } 

    private void action2() { 
     System.out.println("action2"); 
    } 

    private enum Option { 
     Option1, Option2; 

     private InvokeAction methodToExecute; 

     public void setMethodToExecute(InvokeAction methodToExecute) { 
      this.methodToExecute = methodToExecute; 
     } 

     public void execute() { 
      methodToExecute.execute(); 
     } 
    } 

    @FunctionalInterface 
    private interface InvokeAction { 
     void execute(); 
    } 
} 

ので、私は好きでそれを使用することができます。

public class StrategyTest { 
    public static void main(String[] args) { 
     MyStrategy strategy = new MyStrategy(); 
     //user choose 0 or 1 
     strategy.executeChoosenMethod(0); 
     strategy.executeChoosenMethod(1); 
    } 
} 

が、私の列挙型は、より多くのオプションを持っているので、私はOption.Option1.setMethodToExecute(this::action1);でこの部分を好きではないと私は持っているしたいと思いますこれらはすべてenum内にあります。どのような完璧になることは、このようなものです:

public class MyStrategy { 
    public void executeChoosenMethod(int i) { 
     Option.values()[i].execute(); 
    } 

    private void action1() { 
     System.out.println("action1"); 
    } 

    private void action2() { 
     System.out.println("action2"); 
    } 

    private enum Option { 
     Option1(MyStrategy.this::action1), 
     Option2(MyStrategy.this::action2); 

     private InvokeAction methodToExecute; 

     private Option(InvokeAction method) { 
      methodToExecute = method; 
     } 

     public void execute() { 
      methodToExecute.execute(); 
     } 
    } 

    @FunctionalInterface 
    private interface InvokeAction { 
     void execute(); 
    } 
} 

が、列挙型が静的であると私はMyStrategy.thisしてインスタンスを囲むへのアクセスを持っていないので、これは不可能です。私はオプションがあり、values()やvalueOf()などのメソッドを使用すると便利ですが、列挙型が必要ですが、スイッチを増やす代わりに単一行呼び出しを使用したいと考えています。 このようなsometghingを実現する方法がありますか、またはこの列挙型コンストラクタ呼び出しを可能にする回避策がありますかOption1(MyStrategy.this::action1)

+0

'executeChoosenMethod(int i)'は非常に非効率的なメソッドで、OOを使ってモデル化しようとしています。列挙型(またはインタフェース)を渡すと、よりきれいになります。 –

答えて

2

あなたはこのようにそれを実現することができます。

public class MyStrategy { 
    public void executeChoosenMethod(int i) { 
     Option.values()[i].execute(this); 
    } 

    private void action1() { 
     System.out.println("action1"); 
    } 

    private void action2() { 
     System.out.println("action2"); 
    } 

    private enum Option { 
     Option1(MyStrategy::action1), 
     Option2(MyStrategy::action2); 

     private InvokeAction methodToExecute; 

     private Option(InvokeAction method) { 
      methodToExecute = method; 
     } 

     public void execute(MyStrategy s) { 
      methodToExecute.execute(s); 
     } 
    } 

    @FunctionalInterface 
    private interface InvokeAction { 
     void execute(MyStrategy s); 
    } 
} 

これは、ラムダとあなたは、任意のインスタンスメソッドにメソッド参照を作ることができるという事実を使用し、そのインスタンスを最初のパラメータとして渡すことにより、特定のインスタンスでそれらを呼び出すことができます。

+0

InvokeActionの代わりにコンシューマ swch

0

あなたは正しいです。これは列挙型では不可能です。しかし、なぜちょうど良い古いクラスを使用しない:列挙型で

public class MyStrategy { 

    public MyStrategy() { 
     buildUp(); 
    } 

    public void executeChoosenMethod(int i) { 
     actions.get(i).execute(); 
    } 

    private void action1() { 
     System.out.println("action1"); 
    } 

    private void action2() { 
     System.out.println("action2"); 
    } 

    private List<InvokeAction> actions = new ArrayList<>(); 

    private void buildUp() { 
     actions.add(this::action1); 
     actions.add(this::action2); 
    } 

    @FunctionalInterface 
    private interface InvokeAction { 
     void execute(); 
    } 
} 
+0

Option.values()が非常に便利な "printOptions"のようなメソッドがあるので、私は可能な値をコントロールしています。私はtoStringなども使用します。 – swch

関連する問題