State Patterns

By: P. Dyson, B. Anderson
Published in: PLoPD3
Pages: 125-142
Category: Behavioral, Finite State Machines

Summary: Refinement and extension of State [Gamma+95]

Pattern: State Object

Pages: 128-130

To get different behavior from an object depending on its current state, encapsulate the state of the object in a "state" object. Delegate all state-dependent behavior to this state object.

Pattern: State Member

Pages: 130-132

To decide whether a data member belongs in the owning class or in the state object class, if a data member is only required for a single state, place it in the corresponding state object class. If the data member is required for some but not all states, place it in a common superclass. If the data member is state-independent, place it in the owning class and pass it to the state object if necessary.

Pattern: Pure State

Pages: 133

You have a lot of state objects. To reduce the number required, when a state object has no state members, it represents pure state--nothing but state-specific behavior. A pure state object can be shared among any number of objects, reducing the number of state objects required.

Pattern: Exposed State

Pages: 134-136

To prevent the owning class from having too many state-specific, state-dependent methods, expose the state object by defining a method in the owning class that returns a reference to it. Make statement-specific inquiries directly to the state object.

Pattern: State-Driven Transitions

Pages: 136-138

To get the state object to change when the owning object's state changes, have the state object initiate the transition from itself (the current state) to the new state object. This ensures that transitions are atomic and removes state-dependent code.

Pattern: Owner-Driven Transitions

Pages: 138-140

To reuse state object classes among owning classes with different state-transition profiles, if state object classes are used by more than one owning class, and those owning classes have different FSMs, have the owning class initiate the transition between states.

Pattern: Default State

Pages: 140-142

When creating a new owning object, to ensure it has the correct initial state object, use a method, called by the initialize method, that returns the default state object. Redefine this method in a subclass if a different default state is required.