如何在运行时管理策略模式行为?

时间:2013-10-07 18:09:09

标签: java design-patterns

当我怀疑时,我正在阅读Head First Design Patterns书。

在第一章中,研究他们所教授的策略模式,以制作可互换的课程。根据下图:

Strategy Pattern

我的问题:如果我想创建一个带有可视界面的桌面应用程序,并让一些用户拥有比其他用户更多的权限来管理Duck及其行为,该怎么办?因此,他们可以在运行时创建FlyRocketPowered行为。我怎样才能做到这一点?

我的意思是,这些行为对我来说看起来很奇怪,因为我无法看到如何在用户级别对其进行编辑,每次FlyBehaviorQuackBehavior或需要创建/删除/更改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!");
   }
}

在用户级别进行此操作需要做什么?

2 个答案:

答案 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 );