The state pattern is a software design pattern to represent the state of an object. It allows an object to alter its behavior when its state changes. It shows a similarity to the strategy pattern.
The UML class diagram of the state pattern is illustrated below.
To illustrate the state pattern in C#, I’ve created a console application called Skynet. The Skynet application has several states such as Sleep, Eat and TakeOverTheWorld. The Singleton design pattern has been used to create one instance of each state, this is recognizable with the Instance property of the concrete states.
The implementation of the state pattern is illustrated below.
// Context.cs
class Context
{
private State currentState;
public Context(State state)
{
this.currentState = state;
}
public State State
{
get
{
return currentState;
}
set { currentState = value; }
}
public void Request()
{
currentState.Handle(this);
}
}
// State.cs
interface State
{
void Handle(Context context);
}
// SleepState.cs
class SleepState : State
{
private static SleepState instance;
public void Handle(Context context)
{
Console.WriteLine(this.GetType().Name + ": ZZZZzzzZzzzzZ...");
}
public static SleepState Instance
{
get
{
if (instance == null)
{
instance = new SleepState();
}
return instance;
}
set { instance = value; }
}
}
// EatState.cs
class EatState : State
{
private static EatState instance;
public void Handle(Context context)
{
Console.WriteLine(this.GetType().Name + ": Om nom nom nom...");
}
public static EatState Instance
{
get
{
if (instance == null)
{
instance = new EatState();
}
return instance;
}
set { instance = value; }
}
}
// TakeOverTheWorldState.cs
class TakeOverTheWorldState : State
{
private static TakeOverTheWorldState instance;
public void Handle(Context context)
{
Console.WriteLine(this.GetType().Name + ": Just another day at the office!");
}
public static TakeOverTheWorldState Instance
{
get
{
if (instance == null)
{
instance = new TakeOverTheWorldState();
}
return instance;
}
set { instance = value; }
}
}
// The main program
class Program
{
static void Main(string[] args)
{
// Initialize skynet in the Sleep state
Context skynet = new Context(SleepState.Instance);
// Handle the Sleep state
skynet.Request();
// Change the state to the Eat state
skynet.State = EatState.Instance;
// Handle the Eat state
skynet.Request();
// Change the state to the TakeOverTheWorld state
skynet.State = TakeOverTheWorldState.Instance;
// Handle the TakeOverTheWorld state
skynet.Request();
Console.ReadLine();
}
}
Output:
SleepState: ZZZZzzzZzzzzZ... EatState: Om nom nom nom... TakeOverTheWorldState: Just another day at the office!
The VS 2010 project can be downloaded from here.
