State Design Pattern in C# with Examples

The State design pattern is a behavioral design pattern that allows an object to alter its behavior when its internal state changes. This pattern is particularly useful when you have an object that can exist in multiple states, and the object’s behavior depends on its current state.

Key Components of the State Design Pattern

  1. Context: The context is the class that maintains the state of the object and defines the interface to handle various states. In the provided code, the Bug class serves as the context.

  2. State: The state is an interface or an abstract class that defines a set of methods that represent the different states. In the code, the BugState abstract class plays this role.

  3. Concrete States: Concrete state classes are derived from the State interface or abstract class. These classes provide specific implementations of the methods for each state. In the code, OpenState, ClosedState, and ReopenedState are concrete states.

Implementation of the State Design Pattern in C#

1. Context (Bug Class)

The Bug class represents an object that can exist in multiple states (Open, Closed, Reopened). It maintains a reference to the current state (_state) and a list of all possible states (_states).

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]; // Initialize to the default state (Open)
    }

    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);
    }
}

2. State (BugState Abstract Class)

The BugState abstract class defines the interface for different states. It includes three methods: Open(), Close(), and Reopen(), which must be implemented by concrete state classes.

public abstract class BugState
{
    protected Bug _bug;

    public BugState(Bug bug)
    {
        _bug = bug;
    }

    public abstract void Open();
    public abstract void Close();
    public abstract Reopen();
}

3. Concrete States (OpenState, ClosedState, ReopenedState)

Concrete state classes inherit from the BugState abstract class and provide specific implementations for the state-specific behavior.

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");
    }
}

Example Usage

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

}

In the provided code, the Main method demonstrates how to use the State pattern to manage the state of a Bug object and change its behavior based on its state. You can open, close, and reopen the bug, and the behavior is adjusted accordingly.

ClientBugBugStateOpen()Open()"Bug is already open"Close()Close()"Bug is closed"SetState(ClosedState)Reopen()Reopen()"Bug is reopened"SetState(ReopenedState)ClientBugBugState

This State design pattern in C# helps in achieving a clean and maintainable way of managing the behavior of an object with different states without cluttering the code with multiple conditional statements.

Next Post Previous Post
No Comment
Add Comment
comment url