The Strategy Pattern

The Strategy Pattern
CSC 211: Design Patterns
Reading Quiz
Video Game Example
•
•
•
•
Aliens vs. Humans
Both have adjustable life points
Both take damage
Both can recover life points
• Let’s design a class…
• Some functionality is shared, so inheriting from a common superclass
makes sense
• We’ll differentiate between the two classes in their subclasses
Class name
Class
variables
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Class
methods
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
extends
Human
armorPoints : int
<<create>> =
constructor
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
What does Human inherit from LifeForm?
What does Human add to extend its superclass?
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
Alien
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
<<create>> Alien()
So we’re all set … at least for handling life points, right?
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
Alien
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
<<create>> Alien()
Design change!
Characters allowed to recover life points over time
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
recover(i : int) : void
Human
armorPoints : int
Alien
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
<<create>> Alien()
New Problem:
Now Humans have a double advantage (armor + recovery)
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
Alien
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
<<create>> Alien()
recover(i : int) : void
Another Design Change:
Some aliens should be harder than others
They should recover at different rates, not all at once
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
Possible Solution:
Multiple methods
Problems with this?
Alien
maxLifePoints : int
<<create>> Alien()
recoverNone(i : int) : void
recoverFraction(percent : double) void
recoverLinear(i : int) : void
Design Principle #1
You will spend more time
maintaining your code than you will
on the initial design.
Plan for change!
Identify the aspects of your
application that vary and separate
them from what stays the same
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
maxLifePoints : int
<<create>> Alien()
recoverNone(i : int) : void
recoverFraction(percent : double) void
recoverLinear(i : int) : void
Create an interface for the things that vary
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
maxLifePoints : int
<<create>> Alien()
<<interface>>
RecoveryBehavior
calculateRecovery(current : int,max : int) : int
Create an interface for the things that vary
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
maxLifePoints : int
<<create>> Alien()
<<interface>>
RecoveryBehavior
calculateRecovery(current : int,max : int) : int
Create an interface for the things that vary
Create behavior classes that implement the interface
LifeForm
currentLifePoints : int
<<interface>>
RecoveryBehavior
getLifePoints() : int
takeHit(i : int): void
calculateRecovery(current : int,max : int) : int
Human
armorPoints : int
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
maxLifePoints : int
<<create>> Alien()
implements
RecoveryLinear
step : int
<<create>> RecoveryLinear(rStep : int)
calculateRecovery(current : int, max : int) : int
RecoveryNone
<<create>> RecoveryNone()
calculateRecovery(current : int, max : int) : int
RecoveryFractional
percent : double
<<create>> RecoveryFractional(rPercent : double)
calculateRecovery(current : int, max : int) : int
Design Principle #2
Exploit polymorphism in
useful ways.
You can only inherit from
one superclass
Program to an interface,
not an implementation
LifeForm
currentLifePoints : int
<<interface>>
RecoveryBehavior
getLifePoints() : int
takeHit(i : int): void
calculateRecovery(current : int,max : int) : int
Has-A
Alien
recoveryBehavior : RecoveryBehavior
maxLifePoints : int
<<create>> Alien()
recover() : void
setCurrentLifePoints(i : int) : void
Human
armorPoints : int
RecoveryLinear
step : int
<<create>> Human(life : int,armor : int)
setArmorPoints(armor : int) : void
getArmorPoints() : int
<<create>> RecoveryLinear(rStep : int)
calculateRecovery(current : int, max : int) : int
RecoveryFractional
percent : double
<<create>> RecoveryFractional(rPercent : double)
calculateRecovery(current : int, max : int) : int
RecoveryNone
<<create>> RecoveryNone()
calculateRecovery(current : int, max : int) : int
Design Principle #3
Avoid inheriting behavior
Favors flexibility
Favor composition over
inheritance
The Strategy Pattern
SuperClass
Behavior myBehavior
methodA()
methodB()
IS-A
HAS-A
<<interface>>
Behavior
behaviorMethod()
Implements
(also IS-A)
Behavior_v1
behaviorMethod()
SubClassA
methodA() <<override>>
SubClassB
Behavior_v2
behaviorMethod()
The Strategy Pattern
Definition
The Strategy Pattern defines a family of
algorithms, encapsulates each one, and makes
them interchangeable. Strategy lets the
algorithm vary independently from the clients
that use it.
Lab 2
• Due Monday
• Submit your code and tests electronically
• Header the at top of every file you write
/**
* Description of this class
* @author Your Full Name
* Your section number
*/
• ProjectName_LastName
• Zip you eclipse project, name your zip file
» LastName_Lab#