the strategy pattern
DESCRIPTION
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 - PowerPoint PPT PresentationTRANSCRIPT
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
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Class name
Class variables
Classmethods
LifeForm
currentLifePoints : int
getLifePoints() : int
takeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
<<create>> = constructor
What does Human inherit from LifeForm?
What does Human add to extend its superclass?
extends
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
<<create>> Alien()
So we’re all set … at least for handling life points, right?
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
<<create>> Alien()
Design change!Characters allowed to recover life points over time
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
recover(i : int) : void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
<<create>> Alien()
New Problem:Now Humans have a double advantage (armor + recovery)
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
Alien
<<create>> Alien()recover(i : int) : void
Another Design Change:Some aliens should be harder than othersThey should recover at different rates, not all at once
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
AlienmaxLifePoints : int<<create>> Alien()
recoverNone(i : int) : voidrecoverFraction(percent : double) void
recoverLinear(i : int) : void
Possible Solution:Multiple methods
Problems with this?
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() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
AlienmaxLifePoints : int<<create>> Alien()
recoverNone(i : int) : voidrecoverFraction(percent : double) void
recoverLinear(i : int) : void
Create an interface for the things that vary
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
AlienmaxLifePoints : int<<create>> Alien()
Create an interface for the things that vary
RecoveryBehavior
calculateRecovery(current : int,max : int) : int
<<interface>>
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
AlienmaxLifePoints : int<<create>> Alien()
Create an interface for the things that varyCreate behavior classes that implement the interface
RecoveryBehavior
calculateRecovery(current : int,max : int) : int
<<interface>>
LifeForm
currentLifePoints : int
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
AlienmaxLifePoints : int<<create>> Alien()
<<interface>>RecoveryBehavior
calculateRecovery(current : int,max : int) : int
RecoveryLinear
step : int<<create>> RecoveryLinear(rStep : int)
calculateRecovery(current : int, max : int) : int
implements
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
getLifePoints() : inttakeHit(i : int): void
Human
armorPoints : int
<<create>> Human(life : int,armor : int)setArmorPoints(armor : int) : void
getArmorPoints() : int
AlienrecoveryBehavior : RecoveryBehavior
maxLifePoints : int<<create>> Alien()
recover() : voidsetCurrentLifePoints(i : int) : void
<<interface>>RecoveryBehavior
calculateRecovery(current : int,max : int) : int
RecoveryLinear
step : 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
Has-A
Design Principle #3
Avoid inheriting behavior
Favors flexibility
Favor composition over inheritance
The Strategy Pattern
SuperClass
Behavior myBehavior
methodA()methodB()
SubClassA
methodA() <<override>>
<<interface>>Behavior
behaviorMethod()
Behavior_v1behaviorMethod()
SubClassB Behavior_v2behaviorMethod()
IS-A
HAS-A
Implements(also IS-A)
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#