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);으로이 부분이 마음에 들지 개념은 같다 이 모든 것은 열거 형 안에 있습니다. 무엇 완벽 할 것이라고는이 같은 것입니다 :

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에 의해 인스턴스를 둘러싸에 액세스 할 수 없기 때문에이 불가능하다. 내가 옵션 집합을 가지고 있기 때문에 값() 또는 valueOf()와 같은 메소드를 사용하는 것이 편리하지만 열거 형이 필요하다.하지만 스위치를 성장시키는 대신 한 줄을 호출하는 것이 좋다. 이 같은 sometghing을 달성하는 방법에 대한 아이디어가 있습니까? 아니면이 열거 형 생성자 호출을 가능하게하는 해결 방법이 있습니까? Option1(MyStrategy.this::action1)?

+0

'executeChoosenMethod (int i)'는 매우 un-OO 메서드이며, 모델을 만들기 위해 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 대신 Consumer 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

"printOptions"와 같은 메서드가 있으므로 Option.values ​​()가 매우 유용하며 가능한 값을 제어 할 수 있습니다. 또한 toString 등을 사용할 수 있습니다. – swch