DCSIMG
State Pattern - Gil Fink's Blog

Gil Fink's Blog

Fink about IT

News

Microsoft MVP

My Facebook Profile My Twitter Profile My Linkedin Profile

Locations of visitors to this page

Creative Commons License

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2013 Gil Fink

Hebrew Articles

Index Pages

My OSS Projects

English Articles

State Pattern

State Pattern

This post is a post in the design patterns series I’m writing.
The post will describe why and how to use the state design pattern and will
have a C# example of how to implement it.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern 
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern

Creational patterns
Singleton pattern
Abstract Factory pattern
Prototype pattern
Factory Method pattern
Builder pattern

Behavioral Patterns
Strategy pattern
Iterator pattern 
Template method pattern
Command pattern
Chain of responsibility pattern 
Mediator pattern
Memento pattern

State Pattern  
The state design pattern enables us to change the object’s behavior according
to its internal state. The pattern is sometimes described as a dynamic version 
of the strategy pattern. The changing of the state is done by an inner object which
has different subclasses that represent the relevant behavior. 
 
Use Cases for the State Pattern

You should use the pattern in the following cases:

  • An object’s behavior depends on it’s current state and you need to change
    it behavior in runtime according to it’s state.
  • The inner operations are becoming complex with a lot of conditional statements
    that depend on the object’s inner state.
  • You need flexibility in assigning requests to their handlers.

UML Diagram   
State Pattern    

Example in C#
The following code is an example of how to implement the pattern:

    #region State

    public interface IState

    {

        void Handle(StateContext context);

    }

    #endregion

    #region Context

    public class StateContext

    {

        #region Properties

        /// <summary>

        /// The current inner state

        /// </summary>

        public IState State { get; set; }

        /// <summary>

        /// An inner counter of this context

        /// </summary>

        public int Counter { get; set; }

        #endregion

        #region Ctor

        /// <summary>

        /// Construct a new StateContext with the

        /// given first state

        /// </summary>

        /// <param name="state">The first state of the object</param>

        public StateContext(IState state)

        {

            State = state;

        }

        #endregion

        #region Methods

        /// <summary>

        /// Send a request to be handled by the inner state

        /// behavior

        /// </summary>

        public void Request()

        {

            State.Handle(this);

        }

        #endregion

    }

    #endregion

    #region Concrete State

    public class ConcreteStateA : IState

    {

        #region IState Members

        public void Handle(StateContext context)

        {

            context.Counter += 2;

            // change the context state to a new state

            context.State = new ConcreteStateB();

        }

        #endregion

    }

    public class ConcreteStateB : IState

    {

        #region IState Members

        public void Handle(StateContext context)

        {

            context.Counter -= 1;

            // change the context state to a new state

            context.State = new ConcreteStateA();

        }

        #endregion

    }

    #endregion

The implementation of state depends on inheritance. The main issues is to
understand that every concrete state is responsible to change the current 
context behavior to the next context behavior in the chain of behaviors. The
example I gave is simple and can be run with this code:

   // initialize a context with a first state behavior

   StateContext context =

      new StateContext(new ConcreteStateA());

   context.Request();

   Console.WriteLine("The current counter need to be 2: {0}",

      context.Counter);

   context.Request();

   Console.WriteLine("The current counter need to be 1: {0}",

      context.Counter);

   context.Request();

   Console.WriteLine("The current counter need to be 3: {0}",

      context.Counter);

   Console.Read();

Summary
To sum up the post, the state pattern is very simple to implement as you can
see form the example I gave above. The pattern is very effective in graphic tools or
in game programing. Even so, the pattern is not commonly used in programming.
The next pattern in the series will be the visitor pattern.

Comments

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# August 2, 2008 1:58 AM