当我怀疑时,我正在阅读Head First Design Patterns书。
在第一章中,研究他们所教授的策略模式,以制作可互换的课程。根据下图:
我的问题:如果我想创建一个带有可视界面的桌面应用程序,并让一些用户拥有比其他用户更多的权限来管理Duck及其行为,该怎么办?因此,他们可以在运行时创建FlyRocketPowered
行为。我怎样才能做到这一点?
我的意思是,这些行为对我来说看起来很奇怪,因为我无法看到如何在用户级别对其进行编辑,每次FlyBehavior
,QuackBehavior
或需要创建/删除/更改Duck
子类,用户必须通过创建/删除/更改类来要求我修改源代码,但这不是我们想要的,我们需要更多与开发人员无关的东西
修改
说我想制作一个屏幕Add Fly Behavior
(只是添加,而不是编辑,不删除),会有两个字段,第一个是Behavior Name
,第二个是内容到在调用fly()
方法时打印。
通过编辑源代码,我可以通过创建这样的类来实现:
public class FlyRocketPowered implements FlyBehavior {
public void fly() {
System.out.println("I’m fl ying with a rocket!");
}
}
在用户级别进行此操作需要做什么?
答案 0 :(得分:3)
首先,我想说我喜欢这本书。这是我最喜欢的编程书。
对于你的问题:我认为你错过了一点战略模式;) 目标不是让用户在运行时创建新行为。但是使用这种模式,你可以给你的'管理员'一些面板给任何鸭子任何可用的行为。因此,行为仍然是在编译时生成的 。但是你可以在运行时交换行为
此外,就像一个funfact: 完全可以让你的'admin'在运行时创建新的Behaviors。看看Java compiler api。但是如果你考虑这样做,请记住安全漏洞有多大,以及最糟糕的客户是多么难以想象的愚蠢。
答案 1 :(得分:1)
请注意,策略是可以具有属性的类的实例。所以你可以创建一个TextOutputFlyBehavior
类来输出一个可以在运行时设置的字符串。然后,不同的duck-types可以接收相同Strategy类的不同实例,这些实例的行为相同但数据不同。
public class TextOutputFlyBehavior implements FlyBehavior {
private final String message;
public TextOutputFlyBehavior(String message) {
this.message = message;
}
public void fly() {
System.out.println(message);
}
}
[...]
// some hardcoded behaviors:
FlyBehavior propellerFlyBehavior = new TextOutputFlyBehavior("I am flying with a propeller!")
FlyBehavior rocketPoweredFlyBehavior = new TextOutputFlyBehavior("I am flying with a rocket!")
// a user-provided behavior:
BufferedReader userInput = new BufferedReader( new InputStreamReader(System.in) );
System.out.println("Enter text for your custom duck: ");
FlyBehavior customFlyBehavior = new TextOutputFlyBehavior( userInput.readLine() );
// creating the ducks using these behaviors
Duck propellerDuck = new Duck( propellerFlyBehavior );
Duck rocketDuck = new Duck( rocketPoweredFlyBehavior);
Duck customDuck = new Duck( customFlyBehavior);
// when behavior strategies are immutable like this one, they can be reused
Duck propellerDuck2 = new Duck( propellerFlyBehavior );
Duck propellerDuck3 = new Duck( propellerFlyBehavior );