Changing behavior with the State Pattern
In this article, we are going to take a look at the State Pattern. Let’s get into it!
Introduction
The State Pattern is a Behavioral Pattern in which the behavior of a class changes based on its state. This pattern implements a state machine in an object-oriented way and can be a solution to the problem where an object has to change its behavior at runtime without using large monolithic conditional statements.
State Machine
But what is a state machine? Basically, a state machine is a mathematical abstraction that stores the status of something at a given time. It will read a series of external inputs, does some operations and eventually switch to a different state. There are several real-world examples like elevators, whose sequence of stops is determined by the floors requested by riders or traffic lights, which change sequence when cars are waiting.
The pattern
So, with the State pattern, we create objects which represent various States and a Context object whose behavior varies as its state object changes.
The Context is class that presents a single interface to the outside world where we will keep a pointer to the current State. To change the State of the state machine, we will have to change the current State pointer.
We will also create an abstract class State on which every State will be based.
The State Pattern is useful when an object’s behavior depends on its state and it must change its behavior at run-time or when we have operations that have multipart conditional statements that depend on the object’s state.
This pattern is similar to Strategy but in this last one, the choice of algorithm is more stable. The State Pattern has also the same structure as the Bridge Pattern but they solve different problems: State allows the behavior of an object to change along with its State, while Bridge aims to “decouple an abstraction from its implementation so that the two can vary independently”.
Example
Now, let’s make a very simple example with PHP. And because it is always funnier, we are going to say that we are making an awesome video game despite the fact that it is unlikely that we really create a video game with PHP.
First, let’s define our interface for our States:
interface EnemyState
{
public function groan();
}
Now, we can create a few States:
class NotAngry implements EnemyState
{
public function groan(): String
{
echo 'Groan';
}
}class Angry implements EnemyState
{
public function groan()
{
echo 'Groan louder';
}
}class VeryAngry implements EnemyState
{
public function groan()
{
echo 'GROAN LOUDER';
}
}
And now we can create our Context:
class Enemy
{
protected $state; public function __construct(EnemyState $state)
{
$this->state = $state;
} public function setState(EnemyState $state)
{
$this->state = $state;
} public function groan()
{
$this->state->groan();
}
}
And it can be used like so:
$hero = new Hero();
$enemy = new Enemy(new NotAngry());$hero->move();
$enemy->groan();$hero->fire($enemy);
$enemy->setState(new Angry());
$enemy->groan();$hero->fire($enemy);
$enemy->setState(new VeryAngry());
$enemy->groan();
Conclusion
Through this article we saw how works the State Pattern and on which principles it relies. We saw how useful it can be and how to implement it with a really simple example. In brief, the State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class. In this pattern, we define a Context, an abstract State and some concrete States.
One last word
If you like this article, you can consider supporting and helping me on Patreon! It would be awesome! Otherwise, you can find my other posts on Medium and Tumblr. You will also know more about myself on my personal website. Until next time, happy headache!