在使用设计模式时,您可以在多大程度上防止修改现有代码?
Posted
技术标签:
【中文标题】在使用设计模式时,您可以在多大程度上防止修改现有代码?【英文标题】:Up to what extent can you prevent modifying existing code when using design patterns? 【发布时间】:2015-07-04 16:22:49 【问题描述】:我正在学校学习设计模式课程,并且已经阅读了 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 类并希望将其作为参数添加到 returnBehavior()
,我是否还需要修改 main()
?
可以进一步改善这种情况吗?
【问题讨论】:
你应该看看dependency injection 和它的各种框架。 @Synchro 请阅读:What should I do when someone answers my question 【参考方案1】:你在这里做的是依赖注入,你将 FlyBehaviour 注入到 Duck 中。有时当使用像这样的依赖注入时,你可以有一个注入链。例如,如果您希望将速度策略注入到 FlyBehaviour 中,您可能会有类似的内容。
Duck mallard = new MallardDuck(new FlyWithWings(new FastSpeed()));
如果 main 和任何其他使用 Duck 的类必须了解所有这些类并且每次都必须更改这些类,那就不好了。更好的解决方案是使用一个依赖注入容器,它负责创建这些类中的每一个。然后在main中你可以调用这样的东西
Duck mallard = (Duck) Container.get('Duck');
容器负责创建注入所需的所有实例。因此,要回答您的问题,您需要在需要新策略时更改代码,但至少这样它只在一个地方,而不是在整个代码中,可能有很多文件。
【讨论】:
【参考方案2】:在当前示例中,您对传递给工厂的参数进行硬编码,从而决定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
内联
【讨论】:
以上是关于在使用设计模式时,您可以在多大程度上防止修改现有代码?的主要内容,如果未能解决你的问题,请参考以下文章
ImageMagick 在将 PSD 文件转换为 GIF、PNG、JPG 文件时可以在多大程度上保留剪切路径?