Design Pattern #10: State Pattern
These are my notes for the book Headfirst Design Patterns.
Example
Gumball machine.
Implementation 101: focus on action
-
Define states: No quarter; Has quarter; Out of gumballs; Gumballs sold
-
Use instance variable to hold state
final val SOLD_OUT:Int = 0 final val NO_QUARTER:Int = 1 final val HAS_QUARTER:Int = 2 final val SOLD:Int = 3 var state:Int = SOLD_OUT
-
Define actions: insert quarter; eject quarter, turn crack, dispense
-
For each action, create a method using conditional statements to determine which behavior is appropriate in each state.
def insertQuarter = state match { // go through every state case HAS_QUARTER | SOLD_OUT | SOLD => println("can't insert quarter now") case NO_QUARTER => {state = HAS_QUARTER;} // change state }
- Not very flexible for adding new states
- State transitions are not explicit --> buried in
if
statements.
Implementation 201: focus on state
-
Localize behavior for each state: each state implements its own actions.
-
Define a
State
interface that contains a method for every action.
abstract class State{ def insertQuarter:Unit def ejectQuarter:Unit def turnCrank:Unit def dispense:Unit }
- Implement a
State
class for every state.
class NoQuarterState(machine: GumballMachine) extends State{ // compose with the machine def insertQuarter = machine.setState(machine.hasQuarterState) // change machine's state def ejectQuarter = println("cannot eject quarter") def turnCrank = println("no quarter") def dispense = println("no quarter") }
- Delegate to the state class in parent object.
class GumballMachine { val hasQuarterState = new HasQuarterState(this) var state:State = new NoQuarterState(this) // start with no quarter def setState(_state: State):Unit = state = _state def insertQuarter = state.insertQuarter // delegate }
Definition
- Allows an object to alter its behavior when its internal state changes.
- Similar to strategy pattern:
- strategy pattern: client specifies the strategy that is composed
- state pattern: client usually knows very little about internal state
Comments
Comments powered by Disqus