Monday, 15 October 2007

State Design Pattern in Java

Discussing more about Design Patterns today we will discuss basics of State Design Pattern.

Well Objects are often discussed in terms of having a "state" .For instance, one can say that the exact behavior of an object's getColor() method is different if the "color" property of the given object is set to "blue"
instead of "red" because getColor() returns a different value in the two situations.

Furthermore, the object may make decisions at run time as to exactly what to do dependent upon the values its properties possess like the below example


public boolean getColorValue()
{
if(getColor()==Color.GREEN)
{
.......
return true;
}
else
{
.......
return false;
}
}



Surely One issue with the above solution is that it is a hard-coded logic solution,
not an architected solution.Hence we need to ensure we must
change object behavior at run-time depending on that state

Hence our intent is to Allow an object to alter its behavior when its internal state changes.The object will appear to change its class. [GoF, p305]

The State pattern is thus the solution to the problem of how to make behavior depend on state.

1) Define a "context" class to present a single interface to the outside world.

2) Define a State abstract base class.

3) Represent the different "states" of the state machine as derived classes of the State base class.

4) Define state-specific behavior in the appropriate State derived classes.

5) Obviously maintain a pointer to the current "state" in the "context" class.

6) So Finally To change the state of the state machine, change the current "state" pointer.

Benefits:

1) Easy To Add New States.
2) Allows state transition logic to be be incorporated into a state object rather than
in a if or switch statement
3) Helps avoid inconsistent states since state changes occur using just the one
state object and not several objects or attributes.(For Example: Switch statment with inconsistent breaks...)

Below Section Gives an example of this pattern.


class ProjectCurrentState {

private State m_current_state;

public ProjectCurrentState() {
m_current_state = new RequirementsStage();
}

public void set_state( State s ) {
m_current_state = s; }

public void pull() {
m_current_state.pull( );
}
}

interface State {
void pull();
}

class RequirementsStage implements State {
public void pull() {
System.out.println( "Requirements Stage" );
}
}

class DesignStage implements State {
public void pull() {
System.out.println( "Design Stage" );
}
}

class CodingStage implements State {
public void pull() {
System.out.println( "Coding Stage" );
}
}

class TestingAndMaintainenceStage implements State {
public void pull() {
System.out.println( "TestingAndMaintainence Stage" );
}
}

public class StateDesignPattern {
public static void main( String[] args ) {
ProjectCurrentState chain = new ProjectCurrentState();
chain.pull();
chain.set_state(new DesignStage());
chain.pull();
}
}



Hope this explanation helps.Please do suggest if any.

5 comments:

Anonymous said...

Thank you, Prashant. Very well written, please cover other patterns.

JP said...

Anonymous,

Thanks a lot for your encouragment.

Thanks
Prashant

sneha prashant said...

Thanks a lot Prashant,

It is very useful and easy to understand.

Unknown said...

Very simple and straight forward explanation.
Thanks a lot!

Anonymous said...

Thanks Prashant, Good one on state pattern