我试图从我的代码中删除大的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访问封闭的实例。我需要枚举,因为我有一组选项,并且使用像values()或valueOf()这样的方法很方便,但我想要的是单行调用而不是增长开关。
您是否有任何想法如何实现这样的问题,或者是否有任何解决方法可以使此枚举构造函数调用成为可能Option1(MyStrategy.this::action1)
?
答案 0 :(得分:3)
使用枚举,您可以像这样实现它:
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);
}
}
这使用了lambda的事实,你可以对任意实例方法进行方法引用,并通过将实例作为第一个参数传入,在特定实例上调用它们。
答案 1 :(得分: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();
}
}