【设计模式之状态模式 -- C++】

状态模式 -- 状态切换,行为变化

状态模式(State Pattern)允许一个对象在其内部状态改变时改变它的行为。这种模式下,对象看起来似乎修改了它的类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。将状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

组成
  1. 定义状态接口(State):这个接口将封装与上下文的一个特定状态相关的行为。

  2. 创建具体状态类(Concrete States):这些类实现了状态接口,每个类对应一种状态,并实现在该状态下应有的行为。

  3. 定义上下文(Context):这个类包含一个指向状态对象的引用,这个引用可以用来改变其行为。

实现伪代码:

cpp 复制代码
// State 接口声明了特定状态下的行为
interface State {
    method1();
    method2();
}

// ConcreteStateA 和 ConcreteStateB 实现了 State 接口
class ConcreteStateA : State {
    method1() { // 实现细节 }
    method2() { // 实现细节 }
}

class ConcreteStateB : State {
    method1() { // 实现细节 }
    method2() { // 实现细节 }
}

// Context 类包含一个 State 类型的对象,并允许设置当前状态
class Context {
    private State state;

    setState(State state) {
        this.state = state;
    }

    method1() {
        state.method1();
    }

    method2() {
        state.method2();
    }
}
优点
  1. 封装性:状态模式通过将每个状态封装到一个类中,将与状态相关的行为局部化,并且将不同状态的行为分割开来,增强了系统的封装性。
  2. 去除庞大的条件分支语句:状态模式避免了在操作中使用大量的条件分支语句,使得状态的转换更加明确,且易于管理和维护。
  3. 扩展性:由于状态是由类表示的,所以可以很容易地添加新的状态,符合开闭原则。
  4. 职责清晰:每个状态类只关注于一种状态的行为实现,使得职责分配明确。
使用场景
  1. 对象的行为依赖于其状态:当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变其行为时,可以使用状态模式。
  2. 复杂的条件分支需要简化:当一个操作中包含庞大的多分支结构,并且这些分支依赖于对象的状态时,状态模式可以将每一分支转换为一个状态类的一个实现。
  3. 跨类的状态转换:当状态的转换逻辑分散在多个类中时,使用状态模式可以将这些逻辑集中管理,使得状态转换更加清晰和集中。
  4. 状态模式也常用于实现有限状态机:在需要通过一系列输入导致不同状态之间转换和操作的场景中,状态模式提供了一种清晰的方式来实现这种机制。

总的来说,状态模式适用于对象状态多变且相互依赖,需要在运行时根据状态改变对象行为的场景。通过使用状态模式,可以使得状态转换逻辑更加清晰,易于扩展和维护。

实现
  1. state接口
cpp 复制代码
class State {
public:
    virtual void handleRequest() = 0;
    virtual ~State() = default;
};
  1. 具体状态实现a,b
cpp 复制代码
class ConcreteStateA : public State {
public:
    void handleRequest() override {
        std::cout << "ConcreteStateA handles request." << std::endl;
    }
};
class ConcreteStateB : public State {
public:
    void handleRequest() override {
        std::cout << "ConcreteStateB handles request." << std::endl;
    }
};
  1. 上下文
cpp 复制代码
class Context {
private:
    std::unique_ptr<State> state;
public:
    Context(std::unique_ptr<State> state) : state(std::move(state)) {}
    void setState(std::unique_ptr<State> newState) {
        state = std::move(newState);
    }
    void request() {
        state->handleRequest();
    }
};
  1. 测试
cpp 复制代码
int main() {
    Context context(std::make_unique<ConcreteStateA>());
    context.request(); // 输出: ConcreteStateA handles request.

    context.setState(std::make_unique<ConcreteStateB>());
    context.request(); // 输出: ConcreteStateB handles request.

    return 0;
}
  1. 结果
shell 复制代码
ConcreteStateA handles request.
ConcreteStateB handles request.
相关推荐
charlie11451419122 分钟前
精读C++20设计模式:行为型设计模式:中介者模式
c++·学习·设计模式·c++20·中介者模式
楼田莉子29 分钟前
Qt开发学习——QtCreator深度介绍/程序运行/开发规范/对象树
开发语言·前端·c++·qt·学习
oioihoii1 小时前
超越 std::unique_ptr:探讨自定义删除器的真正力量
c++
Gohldg1 小时前
C++算法·贪心例题讲解
c++·数学·算法·贪心算法
天若有情6731 小时前
C++空值初始化利器:empty.h使用指南
开发语言·c++
远远远远子1 小时前
类与对象 --1
开发语言·c++·算法
无敌最俊朗@2 小时前
C/C++ 关键关键字面试指南 (const, static, volatile, explicit)
c语言·开发语言·c++·面试
利刃大大3 小时前
【高并发服务器】三、正则表达式的使用
服务器·c++·正则表达式·项目
虫师c3 小时前
分布式系统设计模式:从理论到实践
微服务·设计模式·系统架构·高可用·分布式系统
半旧夜夏3 小时前
【设计模式】核心设计模式实战
java·spring boot·设计模式