Advertisment

State Pattern

author-image
CIOL Bureau
Updated On
New Update

Avijeet Dash, Satyabrata

Dash
and Bhaskar V

Advertisment

Intent

Advertisment

Allow an object to alter its behavior when its internal State changes. The

object will appear to change its class.

In 30 Seconds

Advertisment

The catch here is ‘implementing discrete object states using explicit

classes’. Many a times we deal with objects, which have a number of discrete

states and the object’s behavior depends on the flow of State transitions. For

example: an object like TCPConnection would go from states like Established,

Listen to Closed. We have two options to implement this. One, we keep all these

states as constant identifiers and clutter the code with conditional logic to

keep checking the states, doing the State change and the respective action for a

particular State. Second approach is to define different State classes, this is

what State Pattern stands for and this adds perfume to the code if long

conditional code in one class stinks.

Advertisment

Motivation

From an object collaboration angle, two kinds of objects come into picture.

One is the ‘Context’ and other is the ‘State’. Context is the object,

which goes through all different states. The Pattern suggests having a composite

relationship between the Context and State. Let the Context keep an object

reference to the State. All different states are Concrete state classes

inheriting from an abstract State class. The State classes implement the

handle() method which localizes the actions to be taken on an event in the State

machine. The Client configures the Context with the initial State and then the

States take care of the State transition as well as the action to be performed.

For example: TCPConnection will have TCPEstablished, TCPListen and TCPClosed

State classes. TCPEstablised will implement the handle() method where it will

dictate the things to do on a connection being established and the State

transition after that.

Advertisment

State Pattern has many benefits: it makes State transition explicit,

localizes the State specific behavior and partitions behavior for different

states.

Structure

Sample Code

Advertisment

State.java

Advertisment
abstract class State
{
        public abstract void setCurrentState(Context c);

        public abstract void handle();

        public abstract void prt();
}

ConcreteStateA.java — implemented as Singleton
class ConcreteStateA extends State
{
         private static ConcreteStateA _currentState = null;

         public static State Instance()
        {

                  if (_currentState==null) {
                        _currentState = new ConcreteStateA();
                 
                 }
                 return(_currentState);

        }

         public void setCurrentState(Context c)
       {

                   c.changeState(_currentState);

        }

        public void handle() { this.prt(); }

        public void prt()

        {
                 System.out.println("Current state is ConcreteStateA.");

        }

 }

Context.java

class Context
{
      public Context() { _state = ConcreteStateA.Instance(); }

      public void request() { _state.handle(); }

      public void changeState( State s) { _state = s; }

      private State _state;
}
Client Code 
Context context = new Context();

State concreteConcreteStateA = ConcreteStateA.Instance();
context.request();

// State having a handle to Context
concreteConcreteStateA.setCurrentState(context);
context.request();

Complexities simplified

Who defines the State transitions

This can be done either by the State or the Context. Moving the State

transition logic to State classes make the State classes aware of each other,

which kind of make them dependent. On the other hand this decentralization helps

extend the system with more states and easy to modify the Context.

State Pattern — implemented as a look up table

This is a different approach to structure the State-driven code. For each

State, a table maps every possible input to a succeeding State. In effect, this

approach converts the conditional code to a table look up. This has its own pros

and cons. Basically, this approach models the State transitions rather than the

State specific behavior.

State Pattern — dynamic inheritance

The ability to change the State at run time, in a sense is like changing

classes (inheritance structure) at run time. This can be viewed as dynamic

inheritance, which is achieved using State Pattern.

Also Known as and Related Patterns

State objects can be used as flyweight if they don’t have any instance

variables representing its intrinsic State.

tech-news