| Type | Behavioral |
| Purpose | Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. |
Description
The State pattern enables the context to behave differently depending on the state that it's in. This is achieved by representing each state as a separate class that implements a common State interface.
Implementing the State pattern can ensure that:
- Large monolithic conditional statements can be avoided.
- State transitions can be made more explicit and easier to understand.
- New states can often be added easily with minimal changes to existing code.
Overview
| Context | Maintains a reference to the current State object and delegates state-dependent behaviour to it. |
| State | Defines the interface used by the Context to delegate state-dependent behaviour. |
| ConcreteState | Implements the State interface and provides behaviour associated with a particular state of the Context. |
Implementation
// State
public interface ITrafficLightState
{
void Change(TrafficLight light);
}
// Concrete States
public class GreenLightState : ITrafficLightState
{
public void Change(TrafficLight light)
{
Console.WriteLine("Green light - Go!");
light.State = new YellowLightState();
}
}
public class YellowLightState : ITrafficLightState
{
public void Change(TrafficLight light)
{
Console.WriteLine("Yellow light - Be careful!");
light.State = new RedLightState();
}
}
public class RedLightState : ITrafficLightState
{
public void Change(TrafficLight light)
{
Console.WriteLine("Red light - Stop!");
light.State = new GreenLightState();
}
}
// Context
public class TrafficLight(ITrafficLightState initialState)
{
public ITrafficLightState State { get; set; } = initialState;
// handler
public void Change() => State.Change(this);
}
// Demonstration
public static class StateDemo
{
public static void Execute()
{
var light = new TrafficLight(new RedLightState());
for (var i = 0; i < 5; i++)
{
// request
light.Change();
}
}
}
Summary
For more information, please see here.