If there was a pattern that could be used just about anywhere, in any situation – and still work, what would that pattern be? For me, the answer is the State Pattern. Using a couple of simple modeling scenarios (modeling a Moving Car and modeling a Data Access Layer), I attempt to explain why this pattern is universally applicable.

Modeling a Moving Car

  1. Step 1: Identify all the States that your system can be in. For e.g. – if we are modeling a moving car , the possible states are Moving and Stopped.
  2. Step 2: Identify all the Events (aks actions) that can be taken by your object.  For e.g. – in our car example, the car can Speed up (Accelerate) or Slow Down (Brake).

That’s it! The hard part is over. Once you have identified the states and events as described in the two steps above, it is a matter of following the steps below to completely implement the State pattern.

Define an interface IState which contains the actions (that’s right – the actions (events), not the States! – The states will be the implementers of IState).

DEFINE YOUR EVENTS (Actions)

/// <summary>
/// Place all the possible 'events' in this interface. This will enforce all implementers to implement each event 
/// </summary>
interface IState
{
        void Accelerate();

        void Brake();
}

DEFINE YOUR STATES

Now define your two states – each as a class implementing the above interface. So, the two classes would be MovingState and StoppedState – each of which would have its own implementation of Accelerate and Brake

public class MovingState : IState 
{
       public void Accelerate()
       {
           // speed up the car
           Console.WriteLine("Going faster...");
       }

       public void Brake()
       {
           // slow down the car            
           Console.WriteLine("Slowing down...");

       }
}
public class StoppedState:IState 
{
       public void Accelerate()
       {
           // speed up the car
           Console.WriteLine("Speeding up...");

       }

       public void Brake()
       {
           // stop the car
           Console.WriteLine("Already Stopped..."); 
      }
} 

As you can see, each state has its own implementation of the two events Accelerate and Brake. That’s all there is to the  State Pattern.

SUMMARY

This (the State Pattern) is one of the most powerful patterns in that, it is universally applicable. Consider the example of modeling a DataAccessLayer where you are a) Connecting to a database and b) Fetching Data

Viola – you have your two events (Connect and FetchData). Now, you need to figure out your states. Since your data access layer sits between the database and the domain layer, these states could be – RetrievingData and PushingDataToDomainLayer. And all you have to do is use these events and states as described above – and you will have a full blown State Pattern implementation of your data access layer. Try implementing the State Pattern for any other modeling scenario – example flying a plane or baking cookies. You will find that it is equally applicable.

Download Solution

Anuj holds professional certifications in Google Cloud, AWS as well as certifications in Docker and App Performance Tools such as New Relic. He specializes in Cloud Security, Data Encryption and Container Technologies.

Initial Consultation

Anuj Varma – who has written posts on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.