谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
当前回答
策略公开为接口,模板方法公开为抽象类。这通常在框架中被大量使用。 如。 Spring框架的MessageSource类是用于解析消息的策略接口。客户端使用该接口的特定实现(策略)。
和相同接口AbstractMessageSource的抽象实现,AbstractMessageSource具有解析消息的通用实现,并公开了resolveCode()抽象方法,以便子类可以以自己的方式实现它们。AbstractMessageSource是模板方法的一个例子。
http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html
其他回答
继承与聚合(is-a与has-a)。这是实现同一目标的两种方法。
这个问题显示了选择之间的一些权衡:继承还是聚合
两者的主要区别在于具体算法的选择。
对于Template方法模式,这是在编译时通过子类化模板实现的。每个子类通过实现模板的抽象方法提供不同的具体算法。当客户端调用模板外部接口的方法时,模板会根据需要调用它的抽象方法(内部接口)来调用算法。
class ConcreteAlgorithm : AbstractTemplate
{
void DoAlgorithm(int datum) {...}
}
class AbstractTemplate
{
void run(int datum) { DoAlgorithm(datum); }
virtual void DoAlgorithm() = 0; // abstract
}
相反,策略模式允许在运行时通过包含来选择算法。具体算法由单独的类或函数实现,这些类或函数作为参数传递给策略的构造函数或setter方法。为这个参数选择哪种算法可以根据程序的状态或输入动态变化。
class ConcreteAlgorithm : IAlgorithm
{
void DoAlgorithm(int datum) {...}
}
class Strategy
{
Strategy(IAlgorithm algo) {...}
void run(int datum) { this->algo.DoAlgorithm(datum); }
}
总而言之:
模板方法模式:通过子类化来选择编译时算法 策略模式:通过包容选择运行时算法
相似之处
策略和模板方法模式之间有很多相似之处。策略和模板方法模式都可以用于满足开闭原则,并使软件模块易于扩展而无需更改其代码。这两种模式都表示通用功能与该功能的详细实现的分离。但是,它们在提供的粒度方面略有不同。
差异
以下是我在研究这两种模式时观察到的一些差异:
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.
图片取自微博客。
模板模式用于特定操作具有某些可以根据其他变化的原语行为定义的不变行为。抽象类定义了不变行为,而实现类定义了相关方法。
在策略中,行为实现是独立的——每个实现类定义行为,它们之间没有共享代码。两者都是行为模式,因此被客户以大致相同的方式消费。通常策略只有一个公共方法——execute()方法,而模板可以定义一组公共方法以及一组支持的私有原语,这些原语必须由子类实现。
这两种模式可以很容易地结合使用。您可能有一个策略模式,其中几个实现属于使用模板模式实现的策略家族。
我认为这两种模式的类图显示了差异。
策略 在类中封装算法 图片链接
模板方法 将算法的精确步骤推迟到子类 链接到图片