Title: The Strategy Design Pattern
1The Strategy Design Pattern
- Idea Algorithm Object/Class
- Intent Make a family of algorithms, encapsulate
each one, and make them interchangeable. Strategy
lets the algorithmvary independently from clients
that use them. - Also known as Policy
- Forces
- input depends on the algorithm
- calculations are based on the clients
abstraction (not using clients implementation or
global data)
2Line Breaking Algorithm
- Algorithms for breaking the stream of text into
lines - Clients that need linebreaking get more complex
if they include the linebreaking code - Different algorithms will be appropriate at
different times - SimpleCompositor implements a simple strategy
that determines linebreaks one at a time - TeXCompositor implements the TEX algorithm for
finding linebreaks. This strategy tries to
optimize linebreaks globally, that is, one
paragraph at a time - ArrayCompositor implements the strategy that
selects breaks, so that each row has a fixed
number of items. Its useful for breaking a
collection of icons into rows, for example
3STRATEGY - Motivation
Composition
compositor
Compositor
Traverse()
Compose()
Repair()
SimpleCompositor
TextCompositor
ArrayCompositor
Compose()
Compose()
Compose()
compositor-gtCompose()
4STRATEGY - Applicability
- Use the Strategy pattern when
- many related classes differ only in their
behavior. Strategies provide a way to configure a
class with one of many behaviors - you need different variants of algorithm
- an algorithms uses data that client shouldnt
know about - a class defines many behaviors, and these appear
as multiple conditional statements in its
operations
5STRATEGY - Structure
strategy
Strategy
Context
ContextInterface()
AlgorithmInterface()
ConcreteStrategyA
ConcreteStrategyB
AlgorithmInterface()
AlgorithmInterface()
6STRATEGY - Participants
- Strategy (Compositor)
- declares an interface common to all supported
algorithms. Context uses this interface to call
the algorithm defined by ConcreteStrategy - ConcreteStrategy (SimpleCompositor)
- implements the algorithm using the Strategy
interface - Context (Composition)
- is configured with a ConcreteStrategy object
- maintains a reference to a Strategy object
- may define an interface that lets Strategy access
its data
7STRATEGY - Consequences
- Families of related algorithms
- An alternative to sub-classing
- you can subclass Context class directly to give
it different behaviors - this hard-wires the behavior into Context
- Context becomes harder to understand, maintains,
extend - algorithm cannot be switched dynamically
- Strategies eliminate conditional statements
- A choice of implementations
- Clients must be aware of different Strategies
- a client must understand how strategies differ
before it can select the appropriate one
8STRATEGY - Consequences
- Communication overhead between Strategy and
Context - the Strategy interface is shared by all
ConcreteStrategy classes whether the algorithms
they implement are trivial or complex - some ConcreteStrategies wont use all the
information passed to them through this interface - solution tighter coupling between Context and
Strategy - Increased number of objects
9STRATEGY - Implementation
- Defining the Strategy and Context interfaces
- access to any data a Strategy needs from a
Context and vice versa - pass data in parameters to the Strategy
operations - pass the Context itself to the Strategy, and the
Strategy will request data from the context
explicitly - the Strategy can store a reference to the Context
- Strategies as template parameters
- template ltclass AStrategygt
- class Context
- void Operation() theStrategy.DoAlgorithm()
- private
- AStrategy theStrategy
-
- ContextltMyStrategygt aContext
10Line Breaking Algorithm
- Line breaking a spectrum from simple to very
elaborate algorithms. - Why not hard wire into client?
- Simplify client code
- Change algorithms as need arise at compile- or
even run-time - Support future plugin of algorithms
- General design
11Applicability
- Related classes different behaviour, but not
different interface - Configure a class with behaviour
- Algorithm variants different time space
trade-offs. - Private data algorithm uses data that clients
should not know about - A class with many different behaviours if you
have too many ifs in your code
12Strategy sample Intersection Traffic Lights
Control
The light- switching policy changes by the hour
13The Behavior Varies
- The dumb policy change the green route every 5
seconds - Midnight policy change to green whenever a
sensor detects a vehicle - Rush hour policy double the green time in the
busy route
14A Bad Solution
- Use multiple conditional statement to set the
behavior according to current policy
intersectionnext_green(the_green_route
r) switch (current_policy) case dumb
next_time time constant_time case
midnight if (not the_green_route.is_busy)
then case rush_hour
15Traffic Lights Management
16Strategy General Structure
Define a family of algorithms, encapsulate each
one, and make them interchangeable.
17Strategy Solution (example)Object Diagram
current_policy rush_hour
theIntersection
1 compute_change_time()
2 const_time ( )
3 const_time_is (13)
4 change_time_is (2 13)
18Strategy Consequences
- Easy to add new strategy (or remove an existing
one, etc.) - For instance From 8 a.m. to 10 a.m. there is no
turn left from Balfour to Begin
19Strategy Consequences II
- Easy to factor out similar strategies (using
inheritance)