Also known as Objects for states.
As stated in GoF, p305 :
Allow an object to alter its behaviour when its internal state changes. The object ill appear to change its class.
You should use the State pattern in the following cases :
- You want to change an object's behaviour at runtime depending on its state.
- When you have a class polluted with massive conditionals that alter how it behaves.
- When you have a lot of duplicate code across similar states and transitions of a condition-based state machine.
Participants
- Context
- Interface of interest to clients.
- Maintains an instance of a ConcreteState subclass that defines the current state and its behaviour.
- State
- Interface for the behaviour associated with a particular state of the Context.
- ConcreteStates
- Implement a behaviour associated with a state of the Context.
How to implement
- Declare the State interface - that is, the behaviour that depends on the state.
- Create a ConcreteState subclass for every identified state of the Context. Implement the behaviours of those states.
- Add a reference field of the State in the Context class and its associated setter.
- Replace where needed in the methods of the Context the conditionals with the corresponding calls to the State object.
Note : UML class diagram taken from here
Pros
- Open/Closed principle : It is easy to introduce new ConcreteStates without breaking any existing code.
- Single responsability principle : Separate states/behaviours are defined within separate classes.
- Simplify the code of the Context by eliminating a lot of conditionals.
Cons
- Can be overkill if there are only a few states and they should never change.
Here are some usefull ressources :
- w3sdesign
- A Refactoring guru article.
- A complete example here