【设计模式】之二十三种设计模式--状态模式

状态模式

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

(当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。)

通用类图

抽象状态类

抽象类,负责对象状态定义,并且封装环境角色以实现状态切换

具体状态类

继承抽象类,完成两个职责,本状态的行为管理以及趋向状态处理

环境类

定义客户端需要的接口,负责具体状态的切换

通用源码

//抽象状态类
class State {
protected:
    //定义一个环境类,提供子类访问
    Context* context;
public:
    //设置环境类
    void setContext(Context* c) { context = c; }
    //具有的行为
    virtual void handle1() = 0;
    virtual void handle2() = 0;
};
//具体状态类
class ConcreteState1 : public State {
public:
    //本状态的处理逻辑
    void handle1() override {
        //do something
    }
    //切换到状态2
    void handle2() override {
        context->setCurrentState(Context::state2);
        context->handle2();
    }
};
class ConcreteState2 : public State {
public:
    void handle2() override {
        //do something
    }
    void handle1() override {
        context->setCurrentState(Context::state1);
        context->handle1();
    }
};
//环境类
class Context {
public:
    //定义状态
    static State* state1;
    static State* state2;
    //获得当前状态
    State* getCurrentState() { return currentState; }
    //设置当前状态
    void setCurrentState(State* s) {
        currentState = c;
        //切换状态
        currentState->setContext(this);
    }
    //行为委托
    void handle1() { currentState->handle1(); }
    void handle2() { currentState->handle2(); }
private:
    //当前状态
    State* currentState;
}
State* Context::state1 = new ConcreteState1();
State* Context::state2 = new ConcreteState2();

优点

结构清晰

遵循设计原则

封装性非常好

缺点

子类会非常多

使用场景

行为随状态改变而改变的场景

条件、分支判断语句的替代者

示例代码

#include <iostream>
#include <string>

using namespace std;

class Context;
class LiftState {
public:
    void setContext(Context* c) { context = c; }
    virtual void open() = 0;
    virtual void close() = 0;
    virtual void run() = 0;
    virtual void stop() = 0;
protected:
    Context* context;
};

class OpenningState;
class ClosingState;
class RunningState;
class StoppingState;
class Context {
private:
    LiftState *liftState;
public:
    LiftState* getLiftState() {
        return liftState;
    }
    void setLiftState(LiftState* l) {
        liftState = l;
        liftState->setContext(this);
    }
    void open() {
        liftState->open();
    }
    void close() {
        liftState->close();
    }
    void run() {
        liftState->run();
    }
    void stop() {
        liftState->stop();
    }
    static OpenningState* openningState;
    static ClosingState* closingState;
    static RunningState* runningState;
    static StoppingState* stoppingState;
};

class OpenningState : public LiftState {
public:
    void open() override {
        cout << "open lift..." << endl;
    }
    void close() override;
    void run() override {
    }
    void stop() override {
    }
};
class ClosingState : public LiftState {
public:
    void open() override {
        context->setLiftState(Context::openningState);
        context->getLiftState()->open();
    }
    void close() override {
        cout << "close lift..." << endl;
    }
    void run() override;
    void stop() override;
};
class RunningState : public LiftState {
public:
    void open() override {
    }
    void close() override {
    }
    void run() override {
        cout << "run lift..." << endl;
    }
    void stop() override;
};
class StoppingState : public LiftState {
public:
    void open() override {
        context->setLiftState(Context::openningState);
        context->getLiftState()->open();
    }
    void close() override {
    }
    void run() override {
        context->setLiftState(Context::runningState);
        context->getLiftState()->run();
    }
    void stop() override {
        cout << "stop lift..." << endl;
    }
};

OpenningState* Context::openningState = new OpenningState();
ClosingState* Context::closingState = new ClosingState();
RunningState* Context::runningState = new RunningState();
StoppingState* Context::stoppingState = new StoppingState();

void OpenningState::close() {
    context->setLiftState(Context::closingState);
    context->getLiftState()->close();
}
void ClosingState::run() {
    context->setLiftState(Context::runningState);
    context->getLiftState()->run();
}
void ClosingState::stop() {
    context->setLiftState(Context::stoppingState);
    context->getLiftState()->stop();
}
void RunningState::stop() {
    context->setLiftState(Context::stoppingState);
    context->getLiftState()->stop();
}

int main() {
    Context* c = new Context();
    c->setLiftState(new ClosingState());
    c->open();
    c->close();
    c->run();
    c->stop();
    return 0;
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦