views:

142

answers:

2

Assume a requirement of implementing a class "CAR".

Now, this class contains various states like "un-ignited", "ignited", "broken-down", "punctured", etc.,

The way I look at to implement this requirement is to have boolean flags aka "properties" in the class and 'check the state' using these boolean flags inside each member function. For example,

CAR.goRacing() 
{
    if(bIsPunctured)
       return ENUM_CANT_DRIVE;

    //Start the Engine... 
}

This implementation, trivial so it might look, starts to become very complicated when the number of states that the object exposes increases. I have also seen occurences where a single state renders the maintenance of the object a lot cumbersome (i am sure that in this case, I am to blame for my programming skills)
Is there a standard way of implementing such a state-driven object?

I have seen Steve Yeggey's Property Pattern, but I am really falling short of a real world example!

Thanks.

+3  A: 

This definitely sounds to be a job for the State Pattern

Basically you create your application ( context ) and define the behavior for some operation into a separate class/interface ( state )

This class will have different implementing subclasses , one per state.

When the state changes, the state object assign the new state to the context. This way you have all the state code into separate classes and avoid the classical spaghetti code.

EDIT

Here's the simplest implementation I could think of.

Suppose you have a "Pet" A pate does something according to the sate it is into.

When that state is complete, the state changes to the next ( being sleep -> wake up -> play etc. )

I don't even know if this compiles. This is only to get the idea*

//These are the states of the "Pet" class
//sleep -> wake up ->  play -> dinner -> sleep -> wake up .. etc. 
class Pet {

    State currentState;
    static Pet createNew(){
        Pet p = new Pet();
        State s = new Sleep();
        s.setContext( p );
        p.currentState = 
        return p;
    }

    public void doSomething(){ 
        currentState.doSomething();
   }

}   

abstract class State {
    Pet context;
    void setContext( Pet c ) { 
        this.context = c;
    }
    abstract doSomething();
    void sout( Striing message ) { 
        System.out.println( message );
    }
}
class Sleep extends State { 
    public void doSomething(){
       sout( "zzzZZZ ... " );
       State nextState = new WakeUp();
       nextState.setContext( context );
       context.currentState = nextState;
    }
}
class WakeUp extends State { 
    public void doSomething(){
       sout( "uuuaaaaww... zzzz What time is it? ... " );
       State nextState = new Play();
       nextState.setContext( context );
       context.currentState = nextState;
    }
}
class Play extends State { 
    public void doSomething(){
       sout( "boing, boing, poing, poing" );
       State nextState = new Dinner();
       nextState.setContext( context );
       context.currentState = nextState;
    }
}
class Dinner extends State { 
    public void doSomething(){
       sout( "Yum, yum..." );
       State nextState = new Sleep();
       nextState.setContext( context );
       context.currentState = nextState;
    }

}

And then your client class just use it!

Pet myPet = Pet.createNew();

while( I_FeelLikePlaying() ){ 
    myPet.doSomething();
}
OscarRyz
A: 

See here for an improved, taking-advantage-of-.NET-facilities version of the state pattern. A state can be a simple function (which will do most of the time) but it can also be an object (or another state machine)...

Regards,

Andreas

Andreas Huber