Strategy
Intent
Define a family of algorithms, encapsulate each one, and make them
interchangeable. Strategy lets the algorithm vary independently from
the clients that use it.
Problem
If clients have potentially generic algorithms embedded in them, it is
difficult to: reuse these algorithms, exchange algorithms, decouple
different layers of functionality, and vary your choice of policy at
run-time. These embedded policy mechanisms routinely manifest
themselves as multiple, monolithic, conditional expressions.
Discussion
Replace the many, monolithic, conditional constructs with a
Strategy inheritance hierarchy and dynamic binding.
- Identify the protocol that provides the appropriate
level of abstraction, control, and interchangeability for the client.
- Specify this protocol in an abstract base class.
- Move all related conditional code into their own concrete derived classes.
- Configure the original application with an instance of the Strategy
hierarchy, and delegate to that "contained" object whenever the "algorithm"
is required.
"Strategies can provide different implementations of the same
behavior. The client can choose among Strategies with different time
and space trade-offs." [GOF, p318] This sounds exactly like the intent
of the Bridge pattern. The apparent overlap can be explained by
observing that both patterns employ the same composition-delegation
structure. The distinction is in intent: Strategy is a "behavioral"
pattern (the focus is on delegating responsibilities), Bridge is a
"structural" pattern (the focus is on establishing relationships).
The Strategy pattern should only be used when the variation in behavior
is relevant to clients. If this criteria is not satisfied, the additional
abstraction and effort necessary to implement the Strategy pattern is not
justified.
There are two implementations for Strategy. The first is described
above. It uses abstract coupling and composition-delegation. The
second uses C++ templates. It is demonstrated in the second example
that follows, and requires the client to "bind" the choice of algorithm
at compile time.
Structure
Example
A Strategy defines a set of algorithms that can be used
interchangeably. Modes of transportation to an airport is an example
of a Strategy. Several options exist such as driving one's own car,
taking a taxi, an airport shuttle, a city bus, or a limousine service.
For some airports, subways and helicopters are also available as a mode
of transportation to the airport. Any of these modes of transportation
will get a traveler to the airport, and they can be used
interchangeably. The traveler must chose the Strategy based on
tradeoffs between cost, convenience, and tlme. [Michael Duell,
"Non-software examples of software design patterns", Object
Magazine, Jul 97, p54]
Non-software example
Rules of thumb
State is like Strategy except in its intent. [Coplien, Mar96, p88]
State, Strategy, Bridge (and to some degree Adapter) have similar solution
structures. They all share elements of the "handle/body" idiom
[Coplien, Advanced C++, p58]. They differ in intent -
that is, they solve different problems.
Strategy lets you change the guts of an object. Decorator lets you
change the skin. [GOF, p184]
Strategy is to algorithms as Builder is to creation. [Icon, p8-13]
Strategy has 2 different implementations, the first is similar to
State. The difference is in binding times (Strategy is a bind-once
pattern, whereas State is more dynamic). [Coplien, Mar96, p88]
Strategy objects often make good Flyweights. [GOF, p323]
Strategy is like Template Method except in its granularity. [Coplien,
Mar96, p88]
C++ Demos | Java Demos | Lab