请问有人能解释一下模板方法模式和策略模式的区别吗?
据我所知,它们在99%的情况下是相同的 - 唯一的区别在于模板方法模式使用抽象类作为基类,而策略模式则使用接口,由每个具体的策略类实现。
然而,在客户端看来,它们以完全相同的方式被调用 - 这样正确吗?
请问有人能解释一下模板方法模式和策略模式的区别吗?
据我所知,它们在99%的情况下是相同的 - 唯一的区别在于模板方法模式使用抽象类作为基类,而策略模式则使用接口,由每个具体的策略类实现。
然而,在客户端看来,它们以完全相同的方式被调用 - 这样正确吗?
模板模式是用于某个操作具有一些不变行为(可以根据其他可变原始行为来定义)的情况。抽象类定义了不变行为,而实现类定义了相关的方法。
在策略模式中,行为实现是独立的——每个实现类都定义了行为,它们之间没有共享的代码。这两种模式都是行为模式,因此客户端以相同的方式使用它们。通常,策略模式只有一个公共方法——execute()
方法,而模板模式可能会定义一组公共方法以及一组支持私有原语,子类必须实现这些原语。
这两种模式可以很容易地结合使用。您可能会使用策略模式来实现一组属于使用模板模式实现的策略族的多个实现。
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); }
}
if (config.useAlgoA) impl = new AlgoA() else impl = new AlgoB()
的操作),因此这个答案是不正确的。 - Borek Bernardnew ConcreteAlgorithm1()
或new ConcreteAlgorithm2()
来进行选择。显然,选择是在运行时进行的(在编译时选择算法会意味着硬编码)。两者之间的主要区别在于具体算法的实现方式。它是作为子类实现还是作为单独的接口?前者是模板方法模式,后者是策略模式。这个区别可以概括为组合(composition)与继承(inheritance),这是GoF书中的一个常见主题。 - jaco0646策略模式和模板方法模式在许多方面有很多相似之处。两种模式都可以用于满足开闭原则,并使软件模块易于扩展而不改变其代码。两种模式都表示将通用功能与该功能的详细实现分离。然而,它们在提供的粒度方面略有不同。
在研究这两种模式时,我观察到了一些不同之处:
图片来自bitesized博客。
模板方法的例子:
Application.main()
{
Init();
Run();
Done();
}
在这里,您继承应用程序并替换init、run和done上要执行的确切操作。
策略示例:
array.sort (IComparer<T> comparer)
在这里,当编写比较器时,你不需要继承自数组。数组将比较算法委托给比较器。
这两种模式非常相似,客户端代码使用方式也很相似。与上面最流行的答案所说的不同的是,它们都允许在运行时选择算法。
两者之间的区别在于,策略模式允许不同的实现以完全不同的方式来实现所需的结果,而 模板方法模式 指定一个总体算法(即 "模板" 方法),用于实现结果——只留给特定实现(子类)某些模板方法的详细信息。这是通过使模板方法调用一个或多个抽象方法来完成的,这些抽象方法被子类覆盖(即实现),而模板方法本身既不是抽象的,也不被子类覆盖。
客户端代码使用指向具体子类实例的抽象类类型的引用/指针调用模板方法,这可以在运行时确定,就像使用策略模式一样。
模板方法:
策略:
相关帖子:
myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);
但是对于基于模板方法的对象,客户端永远不会这样做。事实上,客户端甚至可能不知道一个对象是基于模板方法的。在模板方法模式中,那些抽象方法甚至可能是受保护的,这种情况下客户端甚至不知道它们的存在。