谁能给我解释一下模板方法模式和策略模式的区别是什么?

据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。

然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?


当前回答

模板模式类似于策略模式。这两种模式在范围和方法上有所不同。

策略用于允许调用者改变整个算法,比如如何计算不同类型的税,而模板方法用于改变算法中的步骤。因此,策略的粒度更粗。模板允许在操作序列中进行细粒度的控制,但允许这些细节的实现有所不同。

另一个主要区别是策略使用委托,而模板方法使用继承。在Strategy中,算法被委托给主题将引用的另一个xxxStrategy类,但在Template中,您可以继承基类并重写方法来进行更改。

从http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html

其他回答

继承与聚合(is-a与has-a)。这是实现同一目标的两种方法。

这个问题显示了选择之间的一些权衡:继承还是聚合

在此设计模式的模板方法中,子类可以覆盖一个或多个算法步骤,以允许不同的行为,同时确保仍然遵循总体算法(Wiki)。

模式名Template方法的意思是它是什么。假设我们有一个方法calculatessomething(),我们想要创建这个方法的模板。此方法将在基类中声明为非虚方法。假设这个方法是这样的。

CalculateSomething(){
    int i = 0;
    i = Step1(i);
    i++;
    if (i> 10) i = 5;
    i = Step2(i);
    return i;

} Step1和Step2方法实现可以由派生类给出。

在策略模式中,基类没有提供实现(这就是为什么基类实际上是类图中的接口)。

经典的例子是排序。根据需要排序的对象数量,创建适当的算法类(merge, bubble, quick等),并将整个算法封装在每个类中。

现在我们可以将排序实现为模板方法了吗?当然可以,但是您不会发现有太多/任何共性可以抽象出来并放置在基本实现中。因此,它违背了模板方法模式的目的。

模板方法模式善于阐明算法的整体步骤,而策略模式适合灵活性和可重用性,因此如果需要,可以将策略组合在一起,例如:jdk8中的许多功能接口,如Comparator.reversed().那么比较(Comparator)是策略的一个角色。

模板方法模式侧重于更高的内聚性,而策略模式则与上下文对象松散耦合以分离关注点。

策略易于维护,因为上下文不知道具体的策略,无论主要算法在上下文中发生什么变化都不会影响策略。另一方面,如果在抽象模板类中改变算法的框架,可能会影响其子类的升级。

策略设计模式

支持组成。 为您提供在运行时更改对象行为的灵活性。 减少客户端代码和解决方案/算法代码之间的耦合。

模板方法设计模式

更喜欢继承而不是组合 在基类中定义算法。算法的各个部分可以在子类中定制。


相似之处

策略和模板方法模式之间有很多相似之处。策略和模板方法模式都可以用于满足开闭原则,并使软件模块易于扩展而无需更改其代码。这两种模式都表示通用功能与该功能的详细实现的分离。但是,它们在提供的粒度方面略有不同。


差异

以下是我在研究这两种模式时观察到的一些差异:

In Strategy, the coupling between the client and strategy is more loose whereas in Template Method, the two modules are more tightly coupled. In Strategy, mostly an interface is used though abstract class can also be used depending on the situation, and concrete class is not used whereas in Template method mostly abstract class or concrete class is used, interface is not used. In Strategy pattern, generally entire behaviour of the class is represented in terms of an interface, on the other hand, Template method is used for reducing code duplication and the boilerplate code is defined in base framework or abstract class. In Template Method, there can even be a concrete class with default implementation. In simple words, you can change the entire strategy (algorithm) in Strategy pattern, however, in Template method, only some things change (parts of algorithm) and rest of the things remain unchanged. In Template Method, the invariant steps are implemented in an abstract base class, while the variant steps are either given a default implementation, or no implementation at all. In Template method, the component designer mandates the required steps of an algorithm, and the ordering of the steps, but allows the component client to extend or replace some number of these steps.


图片取自微博客。