Java 在使用设计模式时,可以在多大程度上防止修改现有代码?
我正在学校上设计模式课,已经阅读了Head-First设计模式的一些章节。我想了解的是,设计模式在多大程度上可以防止重写现有代码 让我们以Java 在使用设计模式时,可以在多大程度上防止修改现有代码?,java,design-patterns,methods,factory,strategy-pattern,Java,Design Patterns,Methods,Factory,Strategy Pattern,我正在学校上设计模式课,已经阅读了Head-First设计模式的一些章节。我想了解的是,设计模式在多大程度上可以防止重写现有代码 让我们以Duck类和FlyBehavior类为例。我在publicstaticvoidmain(String[]args)中有以下代码: Duck mallard = new MallardDuck(new FlyWithWings()); 当您想要添加新策略时,不可避免地要修改main()方法,我这样说对吗?这样,您就可以修改现有的代码,对吗?我特别指的是提到具体
Duck
类和FlyBehavior
类为例。我在publicstaticvoidmain(String[]args)
中有以下代码:
Duck mallard = new MallardDuck(new FlyWithWings());
当您想要添加新策略时,不可避免地要修改main()
方法,我这样说对吗?这样,您就可以修改现有的代码,对吗?我特别指的是提到具体策略类的部分:newflywithwings()。
如果您在代码中实现了factory方法模式,则可以避免提及具体的类(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()
,这是对的吗
可以进一步改善这种情况吗?在当前示例中,您正在对传递给工厂的参数进行硬编码,从而决定编译时的行为
Duck mallard = new MallardDuck(returnBehavior(flyFactory, "wings"));
这可以更改为在运行时插入特定行为,而不是在编译时插入特定行为
:
Duck mallard = new MallardDuck(returnBehavior(flyFactory, args[0]));
通过上述更改,您将永远不必更改main
方法。当在运行时接收到的行为不可用时,您的工厂可以以一种方式编写,即它抛出异常
:
if(behaviorType.equals("wings") {
//...create FlyWithWings
} else{
//throw an appropriate exception indicating that the behavior does not exist
}
这就是说,如果引入了新的行为,那么更改代码是不可避免的。尽管如此,此更改将在一个地方进行,并且在您的应用程序中尽可能地落后,即您的工厂
,这是工厂
的全部要点。另外,当您创建新的FlyBehavior
时,您是通过从现有类扩展来实现的。这与开闭原则相一致
您在这里所做的是依赖注入,您正在将flyBehavior注入Duck。有时候,当使用依赖注入时,您可以有一系列注入。例如,如果你想在FlyBehavior中注入速度策略,你可能会有这样的想法
Duck mallard = new MallardDuck(new FlyWithWings(new FastSpeed()));
如果有main和任何其他使用Duck的类必须了解所有这些类,并且每次都必须更改这些类,那就不太好了。更好的解决方案是使用依赖项注入容器,该容器负责创建这些类中的每一个。那么大体上你可以这样称呼
Duck mallard = (Duck) Container.get('Duck');
容器负责创建注入所需的所有实例。因此,要回答您的问题,您需要在需要新策略时更改代码,但至少这样,它只在一个地方,而不是在整个代码中,可能有许多文件。您应该看看和各种框架。@Synchro请阅读: