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

状态模式

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值