What is the difference between the template method and the strategy patterns?

Viewed 77047

Can someone please explain to me what is the difference between the template method pattern and the strategy pattern is?

As far as I can tell they are 99% the same - the only difference being that the template method pattern has an abstract class as the base class whereas the strategy class uses an interface that is implemented by each concrete strategy class.

However, as far as the client is concerned they are consumed in exactly the same way - is this correct?

19 Answers

The template pattern is used when a particular operation has some invariant behavior(s) that can be defined in terms of other varying primitive behaviors. The abstract class defines the invariant behavior(s), while the implementing classes defined the dependent methods.

In a strategy, the behavior implementations are independent -- each implementing class defines the behavior and there is no code shared between them. Both are behavioral patterns and, as such, are consumed in much the same way by clients. Typically strategies have a single public method -- the execute() method, whereas templates may define a set of public methods as well as a set of supporting private primitives that subclasses must implement.

The two patterns could easily be used together. You might have a strategy pattern where several implementations belong to a family of strategies implemented using a template pattern.

The main difference between the two is when the concrete algorithm is chosen.

With the Template method pattern this happens at compile-time by subclassing the template. Each subclass provides a different concrete algorithm by implementing the template's abstract methods. When a client invokes methods of the template's external interface the template calls its abstract methods (its internal interface) as required to invoke the algorithm.

class ConcreteAlgorithm : AbstractTemplate
{
    void DoAlgorithm(int datum) {...}
}

class AbstractTemplate
{
    void run(int datum) { DoAlgorithm(datum); }

    virtual void DoAlgorithm() = 0; // abstract
}

In contrast, the Strategy pattern allows an algorithm to be chosen at runtime by containment. The concrete algorithms are implemented by separate classes or functions which are passed to the strategy as a parameter to its constructor or to a setter method. Which algorithm is chosen for this parameter can vary dynamically based on the program's state or inputs.

class ConcreteAlgorithm : IAlgorithm
{
    void DoAlgorithm(int datum) {...}
}

class Strategy
{
    Strategy(IAlgorithm algo) {...}

    void run(int datum) { this->algo.DoAlgorithm(datum); }
}

In summary:

  • Template method pattern: compile-time algorithm selection by subclassing
  • Strategy pattern: run-time algorithm selection by containment

I think the Class-Diagrams of both pattern are showing the differences.

Strategy
Encapsulates an algorithm inside a class
Link to image enter image description here

Template Method
Defer the exact steps of an algorithm to a subclass
Link to Image enter image description here

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

Example of a template method:

Application.main()
{
Init();
Run();
Done();
}

Here you inherit from application and substitute what exactly will be done on init, run and done.

Example of a strategy:

array.sort (IComparer<T> comparer)

Here, when writing a comparer, you do not inherit from an array. Array delegates the comparison algorithm to a comparer.

Inheritance versus aggregation (is-a versus has-a). It's two ways to achieve the same goal.

This question shows some of trade-offs between choices: Inheritance vs. Aggregation

No, they are not necessarily consumed in the same way. The "template method" pattern is a way of providing "guidance" to future implementers. You are telling them, "All Person objects must have a Social Security Number" (that's a trivial example but it gets the idea across correctly).

The strategy pattern allows multiple possible implementations to be switched in and out. It is not (usually) implemented through inheritance, but instead by letting the caller pass in the desired implementation. An example might be allowing a ShippingCalculator to be provided with one of several different ways of calculating taxes (a NoSalesTax implementation, and a PercentageBasedSalesTax implementation perhaps).

So, sometimes, the client will actually tell the object which strategy to use. As in

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

But the client would never do that for an object that was based on Template Method. In fact, the client might not even know an object is based on Template Method. Those abstract methods in the Template Method pattern might even be protected, in which case the client wouldn't even know they exist.

I think the major difference is that with template you need an algorithm that does something, but lets say in the middle of that algorithm you want to run different behaviours so you can send an implementation of an interface to make that algorithm dynamically in runtime.

but with strategy you have actually totally different algorithms executions no just a variant of the algorithm, then you chose which algo to run, but template you have just one algo with variants.

At the end you can implement as you want and use template as strategy and viceversa but I see a difference.

Template method pattern is good at clarify the overall algorithm steps, however Strategy pattern is suitable for flexibility and reusibility, so you can combine strageties together if you need, e.g: many functional interfaces in jdk8 like Comparator.reversed().thenComparing(Comparator) is a role of strategy.

Template method pattern is focus more high cohesion, but Strategy pattern is loosely coupled with context object for separating concerns.

Strategy is easy to maintain since the context has no knowlege about concrete strategies, whenever the mainly algorithm is changed in context doesn't affect the strategies. On the other hand, if you changed the sckeleton of the algorithm in abstract template class maybe affect its subclasses to upgrade.

Both of them are different techniques to achieve the same result, so question is to use which when.

  • 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).
Related