Many times we need to develop systems / objects that provides services to outside world. But the response of each service is not always same, it depends upon its current internal state.

When its internal state changes at run-time then its behaviour changes and same services acts differently.

For example,

Suppose our system is a Music System and it provides a service i.e.

  • Press play button to play the music.
  • Press stop button to stop the music.
  • Press next button to play the next song.
  • Press prev button to play the previous song.

But does the music system always behaves as suggested above ?

NO.

Lets suppose initially our music system is not playing any song hence in STOPPED state.

If music system is in STOPPED states then,

  • But pressing any other button except PLAY like STOP, NEXT and PREV will have no effect.
  • Pressing the PLAY button will play the music and will move the system in PLAYING state.

If music system is in PLAYING states then,

  • Pressing stop button will stop the music and move the music system to STOPPED state.
  • Pressing next button will play the next song.
  • Pressing prev button will play the previous song.

So, 2 states of a Music Systems are,

State Diagram of Music System

State Diagram of Music System

 

How to design for such problems in Object Oriented manner?

Answer is : Using State Design Pattern.

Intent of State Design Pattern:

Allow an object to alter its behaviour when its internal state changes. The object will appear to change its class.

Structure for State Design Pattern:

Context and State Transition

Context and State Transition

Define a “context” class to present a single interface to the outside world.

MusicSystem will be our “context” class that will provide following services,

  • Play Music
  • Stop Music
  • Play Next Song
  • Play Previous Song

Define a State abstract base class and based on different “states” of the state machine create derived classes of the State base class.

As there are two states of music system, So, there will be a state class with following derived classes,

  • StoppedState
  • PlayingState

Define state-specific behaviour in the appropriate State derived classes.

e.g.

In STOPPED State,

  • STOP, NEXT and PREV request will have no effect
  • PLAY Request will play the music and will also change the current State of Music System to PLAYING.

In PLAYING State,

  • PLAY request will have no effect
  • STOP Request will stop the music and will also change the current State of Music System to STOPPED.
  • PREV Request will play the previous song.
  • NEXT Request will play the previous song.

Maintain a pointer to the current “state” in the “context” class.

As, music system will always be one of these 2 states at a time. So, our Music System will contain a pointer to store a state and will use this state while deciding actions.

To change the state of the state machine, change the current “state” pointer.

During any action it might be possible that state of Music System will change and then response of requests after that will depend on new State.

If Stop Music Request came and Music System was in currently PLAYING state then its state will change to STOPPED. After that PREV and NEXT request will have no response until Music System comes again in PLAYING State.

Generic Class Diagram of State Design Pattern,

State Design Pattern Class Diagram

State Design Pattern Class Diagram

Wait a minute ! Context contains the Base State’s pointer that points to the object of one of the derived state class. Then how derived class will change the state of Context ?

Answer is

Reference or Pointer to the context will be passed to state class during the request, then derived state class can change the current state of Context class based on its conditions.

No Lets Design for Music System using State Design Pattern,

Music System Class Diagram

Music System Class Diagram

Lets see each class in detail now,

Here MusicSystem is our Context,

 

Now Lets Design Base State Class,

First Derived State Class – StoppedState,

Second derived State Class – PlayingState,

How to use these Music System classes,

This is how we can use State Design Pattern. But wait a minute there are some more points,

  • If we see carefully the above State Design Pattern implementation, then we will found that there are many State objects created and destroyed. Is there any way to minimize such wastage ? Answer is yes using Flyweight Design Pattern.
  • State Design Pattern is different from Strategy Design Pattern in Intent only.

We will discuss above two topics in next article.

Thanks & Happy Designing 🙂