C++ 设计模式 状态模式

以下内容均来自GeekBand极客班C++ 设计模式课程(李建忠老师主讲)

State

“状态变化”模式

在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?“状态变化”模式为这一问题提供一种解决方案。

典型模式

state

Memento

 

动机(Motivation)

在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生改变,不如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。

如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合。

《设计模式》GOF的定义:

允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。

C++ 设计模式 状态模式_第1张图片

示例

下面有一个关于网络的例子,根据网络不同的状态有不同的行为

enum{
    Network_Open,
    Network_Close,
    Network_Connect,
};

class NetworkProcessor{
    NetworkState state;
public:
    //下面的代码也诠释了,只要状态改变了,那么Operation各部分的行为也会发送改变
    void Operation1(){
        if(state == Network_Open){
            state = Network_Close;
        }
        else if(state == Network_Close){
            state = Network_Connect;
        }
        else if(state == Network_Connect){
            state = Network_Open;
        }
    }

    void Operation2(){
        if(state == Network_Open){
            state = Network_Connect;
        }
        else if(state == Network_Close){
            state = Network_Open;
        }
        else if(state == Network_Connect){
            state = Network_Close;
        }
    }

};

单看上述内容,条件反射的想到了策略模式,过多的if和else,对于未来的扩展非常不利。

在原来的表达中。

if  state为Open状态,执行Operation1,则变成Close状态

if  state为Open状态,执行Operation1,则变成Connect状态

那么就结合策略模式,加上上面的状态变化,对程序进行修改

class NetworkState{
public:
    NetworkState * pNext;
    virtual void Operation1() = 0;
    virtual void Operation2() = 0;
    virtual void Operation3() = 0;
    virtual ~NetworkState(){}
};

class OpenState : public NetworkState{
    static NetworkState * m_instance;
public:
    static NetworkState * getInstance(){
        if(m_instance == nullptr){
            m_instance = new OpenState();
        }
        return m_instance;
    }

    void Operation1(){
        //经过Operation1,状态编程Open
        pNext = CloseState::getInstance();
    }

    void Operation2(){
        //经过Operation2,状态编程Connect
        pNext = ConnectState::getInstance();

    }
};
class CloseState : public NetworkState{

};
class ConnectState : public NetworkState{

};

再对NetworkProcessor进行重构:

class NetworkProcessor{
    NetworkState * PState;
public:
    NetworkProcessor(NetworkState * PState){
        this->PState = PState;
    }
    //下面的代码也诠释了,只要状态改变了,那么Operation各部分的行为也会发送改变
    void Operation1(){
        //此时就看PState指向谁了,如果指向的是OpenState1,那么就走OpenState的Operation1();
        PState->Operation1();
        //完成之后,立马更换你的状态,保证下次Operation的时候不会出错
        PState = PState->pNext;
    }
    void Operation2(){
        //此时就看PState指向谁了,如果指向的是OpenState2,那么就走OpenState的Operation2();
        PState->Operation2();
        PState = PState->pNext;
    }
};

整个过程非常的巧妙。

和策略模式异曲同工,都是为了方便扩展。

要点总结

State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。

为不同的状态引入不同的对象使得状态转化变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的——即要么彻底转换过来,要么不转换。

如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。

你可能感兴趣的:(重构)