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

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

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


当前回答

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

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

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

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

其他回答

两者都非常相似,客户端代码以类似的方式使用它们。与上面最流行的答案不同,两者都允许在运行时选择算法。

The difference between the two is that while the strategy pattern allows different implementations to use completely different ways of the achieving the desired outcome, the template method pattern specifies an overarching algorithm (the "template" method) which is be used to achieve the result -- the only choice left to the specific implementations (sub-classes) are certain details of the said template method. This is done by having the the template method make call(s) to one or more abstract methods which are overridden (i.e. implemented) by the sub-classes, unlike the template method which itself is not abstract and not overridden by the sub-classes.

客户端代码使用抽象类类型的引用/指针调用模板方法,该引用/指针指向具体子类之一的实例,该实例可以在运行时确定,就像使用策略模式时一样。


相似之处

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


差异

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

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.


图片取自微博客。

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

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

它们都是不同的技术来达到相同的结果,所以问题是在什么时候使用哪一种。

If you are using a framework or library which you do not have access to the source code and you want to change some behaviors of a class, so you have to go for Template Method. That means inheritance simply. If you are developing a class and it is obvious that some parts of the logic needs to be implemented differently to handle various situations, take the Strategy pattern. Strategy is more SOLID than the Template Method. It covers both Dependency Inversion and Open/Close principles. So it is extendable and also easily testable. If you are developing a class and you do not know what changes will happen in the future, divide your logic into separate and single responsible functions as much as possible. Just that. (Neither Template Method nor Strategy).

策略公开为接口,模板方法公开为抽象类。这通常在框架中被大量使用。 如。 Spring框架的MessageSource类是用于解析消息的策略接口。客户端使用该接口的特定实现(策略)。

和相同接口AbstractMessageSource的抽象实现,AbstractMessageSource具有解析消息的通用实现,并公开了resolveCode()抽象方法,以便子类可以以自己的方式实现它们。AbstractMessageSource是模板方法的一个例子。

http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html