The Strategy Pattern
The Strategy Pattern
1
The Specifications
• Joe works at a company that
produces a simulation game
called SimUDuck.
He is an OO Programmer
and his duty is to implement
the necessary functionality
for the game
2
A First Design for the
Duck Simulator Game
Duck
All ducks quack() and swim(). The
superclass takes care of the implementation
quack()
swim()
display() The display() method is abstract since
//other duck like methods all the duck subtypes look different
3
But now we need the ducks to fly…
Joe, at the shareholders meeting we
decided that we need to crush the
competition. From now on our ducks
need to fly.
Duck
quack()
swim()
display()
fly() All subclasses inherit fly()
MallardDuck RedHeadDuck
display() display()
4
But something went horribly wrong..
• At a demo the program failed to impress anyone –
There were rubber ducks flying across the screen!
What happened? Duck
A localized update to the code
caused a non-local side effect quack()
(flying rubber ducks) swim() By putting fly() in the
display() superclass, Joe gave flying
fly() ability to all ducks including
those that shouldn’t
7
How about an interface?
• Need a cleaner way to make some ducks fly or quack.
– Could take the fly() out of the superclass and make an
Flyable interface with a fly() method. Each duck that is
supposed to fly will implement that interface
– and maybe a Quackable interface as well.
<<Interface>> <<Interface>> Duck
Flyable Quackable
+ swim()
+ fly() + quack() + display()
// other duck like methods
What do you
think about
this design?
9
Embracing Change
• In SOFTWARE projects you can count on one thing
that is constant:
CHANGE
• Solution
– Deal with it.
• Make CHANGE part of your design.
• Identify what vary and separate from the rest.
10
Change is a taste of life
11
Design Principle
Encapsulate
what varies
12
The Constitution of Software Architects
• Encapsulate what varies.
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
13
Embracing Change in Ducks
• fly() and quack() are the parts that vary
• We create a new set of classes to represent each behavior
<<Interface>> <<Interface>>
FlyBehavior QuackBehavior
+ fly() + quack()
14
Design Principle
15
The Constitution of Software Architects
• Encapsulate what varies.
• Program through an interface
not to an implementation
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
16
Design Principle Example
Animal
Program through an implementation
+ makeSound() Dog dog = createDog();
dog.bark();
17
Integrating the Duck Behavior
Instance variables
The behavior variables Duck hold a reference to
are declared as the # flyBehavior : FlyBehavior a specific behavior
behavior interface type. # quackBehavior : QuackBehavior at runtime.
+ performQuack() quackBehavior.quack();
These replace the + performFly()
fly() and quack() + swim() flyBehavior.fly();
+ display()
methods.
+ performQuack()
+ performFly() Composition
+ swim()
+ display()
Instead of inheriting behavior, the duck
get their behavior by being composed
with the right behavior object
19
Design Principle
20
The Constitution of Software Architects
• Encapsulate what varies.
• Program through an interface
not to an implementation
• Favor Composition over
Inheritance
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
• ?????????
21
Putting it together…
public interface QuackBehavior {
void quack();
}
public interface FlyBehavior {
void fly();
} public abstract class Duck {
protected FlyBehavior flyBehavior;
protected QuackBehavior quackBehavior;
...
public performQuack() {
quackBehavior.quack();
}
public performFly() {
flyBehavior.fly();
}
}
22
Putting it together…
public class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public class Quack implements QuackBehavior {
}
public void quack() {
System.out.println("Quack");
}
public class FlyWithWings implements FlyBehavior {
}
public void fly() {
System.out.println("I'm flying!!");
}
}
+ performFly()
+ performQuack()
+ swim() FlyWithWings FlyNoWay FlyRocketPower
+ display() + fly() + fly() + fly()
+ setFlyBehavior(f : FlyBehavior)
+ setQuackBehavior(q : QuackBehavior)
<<Interface>>
QuackBehavior
25
Behavior Reuse <<Interface>>
FlyBehavior
Duck
- flyBehavior : FlyBehavior + fly()
- quackBehavior : QuackBehavior
+ performFly()
+ performQuack()
+ swim() FlyWithWings FlyNoWay
+ display()
+ setFlyBehavior(f : FlyBehavior) + fly() + fly()
+ setQuackBehavior(q : QuackBehavior)
<<Interface>>
QuackBehavior
Plane
- flyBehavior : FlyBehavior
+ performFly()
26
The Strategy Design Pattern
The Strategy Design Pattern defines a family of algorithms,
encapsulates each one, and makes them interchangeable.
Strategy lets the algorithms vary independently from the clients that use
it.
Context manages the data structures
that a concrete strategy operates on.
Defines the generic interface
Context
- strategy : Strategy <<Interface>>
Strategy
+ Context(s : Strategy)
+ setStrategy(s : Strategy) + runAlgorithm()
+ runAlgorithm()
28