谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
谁能给我解释一下模板方法模式和策略模式的区别是什么?
据我所知,它们99%是一样的——唯一的区别是 模板方法模式有一个抽象类作为基础 类,而策略类使用已实现的接口 由每个具体的策略类。
然而,就客户端而言,它们是以完全相同的方式被消费的——这是正确的吗?
当前回答
策略设计模式
支持组成。 为您提供在运行时更改对象行为的灵活性。 减少客户端代码和解决方案/算法代码之间的耦合。
模板方法设计模式
更喜欢继承而不是组合 在基类中定义算法。算法的各个部分可以在子类中定制。
其他回答
我认为这两种模式的类图显示了差异。
策略 在类中封装算法 图片链接
模板方法 将算法的精确步骤推迟到子类 链接到图片
在此设计模式的模板方法中,子类可以覆盖一个或多个算法步骤,以允许不同的行为,同时确保仍然遵循总体算法(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等),并将整个算法封装在每个类中。
现在我们可以将排序实现为模板方法了吗?当然可以,但是您不会发现有太多/任何共性可以抽象出来并放置在基本实现中。因此,它违背了模板方法模式的目的。
两者都非常相似,客户端代码以类似的方式使用它们。与上面最流行的答案不同,两者都允许在运行时选择算法。
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.
客户端代码使用抽象类类型的引用/指针调用模板方法,该引用/指针指向具体子类之一的实例,该实例可以在运行时确定,就像使用策略模式时一样。
不,它们的消费方式不一定相同。“模板方法”模式是为未来的实现者提供“指导”的一种方式。您告诉他们,“所有Person对象都必须有一个社会安全号码”(这是一个微不足道的例子,但它正确地传达了思想)。
策略模式允许在多个可能的实现之间切换。它(通常)不是通过继承实现的,而是通过让调用者传入所需的实现来实现的。例如,允许为ShippingCalculator提供几种不同的计算税收的方法之一(可能是NoSalesTax实现和PercentageBasedSalesTax实现)。
有时候,客户端会告诉对象使用哪种策略。就像在
myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);
但是客户端永远不会为基于模板方法的对象这样做。事实上,客户端甚至可能不知道对象是基于模板方法的。模板方法模式中的那些抽象方法甚至可能受到保护,在这种情况下,客户端甚至不知道它们的存在。
继承与聚合(is-a与has-a)。这是实现同一目标的两种方法。
这个问题显示了选择之间的一些权衡:继承还是聚合