谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
当前回答
两者的主要区别在于具体算法的选择。
对于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); }
}
总而言之:
模板方法模式:通过子类化来选择编译时算法 策略模式:通过包容选择运行时算法
其他回答
不,它们的消费方式不一定相同。“模板方法”模式是为未来的实现者提供“指导”的一种方式。您告诉他们,“所有Person对象都必须有一个社会安全号码”(这是一个微不足道的例子,但它正确地传达了思想)。
策略模式允许在多个可能的实现之间切换。它(通常)不是通过继承实现的,而是通过让调用者传入所需的实现来实现的。例如,允许为ShippingCalculator提供几种不同的计算税收的方法之一(可能是NoSalesTax实现和PercentageBasedSalesTax实现)。
有时候,客户端会告诉对象使用哪种策略。就像在
myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);
但是客户端永远不会为基于模板方法的对象这样做。事实上,客户端甚至可能不知道对象是基于模板方法的。模板方法模式中的那些抽象方法甚至可能受到保护,在这种情况下,客户端甚至不知道它们的存在。
You probably mean template method pattern. You are right, they serve very similar needs. I would say it is better to use template method in cases when you have a "template" algorithm having defined steps where subclasses override these steps to change some details. In case of strategy, you need to create an interface, and instead of inheritance you are using delegation. I would say it is a bit more powerful pattern and maybe better in accordance to DIP - dependency inversion principles. It is more powerful because you clearly define a new abstraction of strategy - a way of doing something, which does not apply to template method. So, if this abstraction makes sense - use it. However, using template method may give you simpler designs in simple cases, which is also important. Consider which words fit better: do you have a template algorithm? Or is the key thing here that you have an abstraction of strategy - new way of doing something
模板方法的例子:
Application.main()
{
Init();
Run();
Done();
}
这里你继承了application,并替换了init, run和done的操作。
策略的例子:
array.sort (IComparer<T> comparer)
在这里,当编写比较器时,您不继承数组。数组将比较算法委托给比较器。
在策略模式中,子类起主导作用,它们控制算法。这里的代码是跨子类复制的。算法的知识和如何实现它分布在许多类中。
在模板模式中,基类具有算法。它最大化了子类之间的重用。由于算法在一个地方,基类保护它。
策略设计模式
支持组成。 为您提供在运行时更改对象行为的灵活性。 减少客户端代码和解决方案/算法代码之间的耦合。
模板方法设计模式
更喜欢继承而不是组合 在基类中定义算法。算法的各个部分可以在子类中定制。
我认为这两种模式的类图显示了差异。
策略 在类中封装算法 图片链接
模板方法 将算法的精确步骤推迟到子类 链接到图片