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

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

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

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

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

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

实现伪代码:

// 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接口
class State {
public:
    virtual void handleRequest() = 0;
    virtual ~State() = default;
};
  1. 具体状态实现a,b
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. 上下文
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. 测试
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. 结果
ConcreteStateA handles request.
ConcreteStateB handles request.
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值