在使用设计模式时,您可以在多大程度上防止修改现有代码?

时间:2015-04-26 07:38:15

标签: java design-patterns methods factory strategy-pattern

我正在学校参加设计模式课程,并阅读了Head First Design Patterns的一些章节。我想知道的是设计模式在多大程度上可以防止重写现有代码。

我们以Duck类和FlyBehavior类为例。我在public static void main(String[] args)中有以下代码:

Duck mallard = new MallardDuck(new FlyWithWings());

我是否正确地说,当您想要添加新策略时,您必须修改main()方法?这样, 修改现有代码,对吗?我特别指的是提到具体策略类的部分:new FlyWithWings().

如果在代码中实现了工厂方法模式,则可能会阻止提及具体类(FlyWithWings):

public FlyBehavior returnBehavior(FlyBehaviorFactory factory, String behaviorType) {
    return factory.getFlyBehavior(behaviorType);
}

因此,请使用以下代码行:

Duck mallard = new MallardDuck(returnBehavior(flyFactory, "wings"));

这样,程序的某个部分不必知道要使用的FlyBehaviorFactory。但是,您的main()方法仍然必须在returnBehavior方法中指定某些参数,以便了解哪个工厂将创建什么策略。因此,我是否正确地说,如果我添加了一个新的FlyBehavior类,并且想将其作为参数添加到main(),您仍然需要修改returnBehavior()

可以进一步改善这种情况吗?

2 个答案:

答案 0 :(得分:0)

在当前示例中,您正在对传递给工厂的参数进行硬编码,从而决定compile time处的行为。

Duck mallard = new MallardDuck(returnBehavior(flyFactory, "wings"));

可以更改为在runtime而不是compile time插入特定行为:

Duck mallard = new MallardDuck(returnBehavior(flyFactory, args[0]));

通过上述更改,您无需更改main方法。当在运行时收到的行为不可用时,您的工厂可以以throws exception的方式编写:

if(behaviorType.equals("wings") {
   //...create FlyWithWings
} else{
  //throw an appropriate exception indicating that the behavior does not exist
}

话虽如此,如果引入新行为,则更改代码是不可避免的。虽然,这种变化将在一个地方,尽可能远在您的应用程序之后,即factory,这首先是factory的全部内容。此外,当您创建新的FlyBehavior时,您是通过从现有类扩展来实现的。这与open-closed principle

一致

答案 1 :(得分:0)

你在这里做的是依赖注入,你正在将FlyBehaviour注入Duck。有时,当使用这样的依赖注入时,您可以进行一系列注射。例如,如果你想要一个速度策略注入FlyBehaviour,你可能会有类似的东西。

Duck mallard = new MallardDuck(new FlyWithWings(new FastSpeed()));

使用Duck的main和任何其他类必须知道所有这些类并且每次都必须改变它们并不好。更好的解决方案是使用依赖注入容器,该容器负责创建这些类中的每一个。然后在main中你可以调用类似这样的东西

Duck mallard = (Duck) Container.get('Duck');

容器负责创建注射所需的所有实例。因此,要回答您的问题,您需要在需要新策略时更改代码,但至少这种方式只能在一个地方而不是整个代码中,这可能是很多文件。