Jul 27, 2015

State Pattern Encapsulation in C#

Classic state pattern is usually implemented by having the Context expose a part of it's interface publicly. This is required in order to allow a State to manipulate the Context in some way. In languages that feature nested classes, such as C#, it's possible to create a solution that provides full encapsulation of the Context.

Nested classes have a special trust agreement with classes they are nested in. By nesting the abstract State class inside the Context class, we allow it to access private and protected members, properties and methods of the Context.

Here, the abstract State acts as a gateway for derived classes to manipulate the Context indirectly. It can perform checks on the data that derived classes want to pass to the Context.

Download the source code or check it out at GitHub directly.
Visual Studio Community is required to compile and run the example.

Baisc implementation of the state pattern using a nested State class might look like this:

Context and nested State class
public class Context
{
  private State currentState;

  public Context(State initialState)
  {
    if (initialState == null) throw new ArgumentNullException("initialState");

    currentState = initialState;
  }

  public void Request()
  {
    currentState.Handle(this);
  }

  public abstract class State
  {
    public abstract void Handle(Context context);

    protected void SetState(Context context, State state)
    {
      // Even though this variable is private
      // it can be modified from this nested class
      context.currentState = state;
    }
  }
}

A concrete State implementation can use the base class methods to access the Context:

Concrete state example
public class ConcreteStateA : Context.State
{
  public override void Handle(Context context)
  {
    // Gateway method
    base.SetState(context, new ConcreteStateB());
  }
}
comments powered by Disqus