State design pattern is a design pattern which helps us to change the state of an object.
State design pattern can be used in cases where we have to track the state of an object and its behavior is dependent on that state.
The State design pattern has two roles:
- An interface for managing the various states of an object
- An abstract class that implements this interface and provides concrete implementations for each of its methods
In this example, the Bug class has three states -Open
,Close
orReOpen
. The Bug class has two methods -SetState()
andGetState()
. TheSetState()
method changes the state of a bug from Open to Closed or Reopened and vice versa. TheGetState()
method returns the current state of a bug.
Lets see the sequence diagram of state design pattern
Complete Source Code
namespace StatePattern
{
class Program
{
static void Main(string[] args)
{
Bug bug = new Bug();
bug.Open(); //Bug is already open
bug.Close();//Bug is closed
bug.Open(); //Bug is already closed
bug.Reopen(); //Bug is reopened
bug.Close(); //Bug is closed
bug.Reopen(); //Bug is reopened
}
}
public class Bug
{
private BugState _state;
private List<BugState> _states;
public Bug()
{
_states = new List<BugState>();
_states.Add(new OpenState(this));
_states.Add(new ClosedState(this));
_states.Add(new ReopenedState(this));
_state = _states[0];
}
public void Open()
{
_state.Open();
}
public void Close()
{
_state.Close();
}
public void Reopen()
{
_state.Reopen();
}
public void SetState(BugState state)
{
_state = state;
}
public BugState GetState(string state)
{
return _states.Find(s => s.GetType().Name == state);
}
}
public abstract class BugState
{
protected Bug _bug;
public BugState(Bug bug)
{
_bug = bug;
}
public abstract void Open();
public abstract void Close();
public abstract void Reopen();
}
public class OpenState : BugState
{
public OpenState(Bug bug) : base(bug)
{
}
public override void Open()
{
Console.WriteLine("Bug is already open");
}
public override void Close()
{
Console.WriteLine("Bug is closed");
_bug.SetState(_bug.GetState("ClosedState"));
}
public override void Reopen()
{
Console.WriteLine("Bug is already open");
}
}
public class ClosedState : BugState
{
public ClosedState(Bug bug) : base(bug)
{
}
public override void Open()
{
Console.WriteLine("Bug is already closed");
}
public override void Close()
{
Console.WriteLine("Bug is already closed");
}
public override void Reopen()
{
Console.WriteLine("Bug is reopened");
_bug.SetState(_bug.GetState("ReopenedState"));
}
}
public class ReopenedState : BugState
{
public ReopenedState(Bug bug) : base(bug)
{
}
public override void Open()
{
Console.WriteLine("Bug is already reopened");
}
public override void Close()
{
Console.WriteLine("Bug is closed");
_bug.SetState(_bug.GetState("ClosedState"));
}
public override void Reopen()
{
Console.WriteLine("Bug is already reopened");
}
}
}