Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在使用设计模式时,可以在多大程度上防止修改现有代码?_Java_Design Patterns_Methods_Factory_Strategy Pattern - Fatal编程技术网

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

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()方法,我这样说对吗?这样,您就可以修改现有的代码,对吗?我特别指的是提到具体

我正在学校上设计模式课,已经阅读了Head-First设计模式的一些章节。我想了解的是,设计模式在多大程度上可以防止重写现有代码

让我们以
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请阅读: