作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正试图从我的代码中删除大的 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)
?
最佳答案
使用枚举你可以像这样实现它:
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);
}
}
这利用了 lambdas 的事实,您可以对任意实例方法进行方法引用,并通过将实例作为第一个参数传入来在特定实例上调用它们。
关于java - 带有内部枚举的策略模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39922554/
我是一名优秀的程序员,十分优秀!