State design pattern in C#

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.

State design pattern in UML

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.

This entry was posted in C# and tagged , , , , , , , , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Why ask?