实现状态驱动的类

时间:2008-12-29 20:17:11

标签: design-patterns class

假设要求实施“CAR”类。

现在,这个类包含各种状态,如“un-ignited”,“ignited”,“broken-down”,“punctured”等,

我实现这个要求的方法是在类中使用布尔标志又称“属性”,并在每个成员函数中使用这些布尔标志“检查状态”。例如,

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

    //Start the Engine... 
}

当对象公开的状态数量增加时,这个实现很简单,看起来很简单,开始变得非常复杂。我还看到了一个状态导致对象的维护很麻烦的事件(我确信在这种情况下,我应该为我的编程技巧负责)
是否有实现这种状态驱动对象的标准方法?

我见过Steve Yeggey的Property Pattern,但我真的没有现实世界的榜样!

感谢。

2 个答案:

答案 0 :(得分:3)

这绝对听起来像是State Pattern

的工作

基本上,您创建应用程序(上下文)并将某些操作的行为定义为单独的类/接口(状态)

这个类将有不同的实现子类,每个状态一个。

当状态改变时,状态对象将新状态分配给上下文。这样,您将所有状态代码放入单独的类中,并避免使用传统的意大利面条代码。

修改

这是我能想到的最简单的实现。

假设你有一个“宠物”一个头脑根据其所处的状态做某事。

当该状态完成时,状态变为下一个状态(正在进入睡眠状态 - >唤醒 - >播放等)

我甚至不知道这是否编译。这只是为了获得想法*

//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;
    }

}

然后您的客户端类只使用它!

Pet myPet = Pet.createNew();

while( I_FeelLikePlaying() ){ 
    myPet.doSomething();
}

答案 1 :(得分:0)

请参阅here以获得改进的,利用.NET设施版本的状态模式。状态可以是一个简单的函数(大部分时间都会执行)但它也可以是一个对象(或另一个状态机)...

此致

安德烈亚斯