状态模式(附C++代码示例)

状态模式的含义

状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。状态模式通过将每个状态封装到类中,并将行为委托到代表当前状态的对象,来使得单个对象在运行时能够动态改变行为。

核心思想及解释

状态模式的核心思想是状态封装。具体来说,状态模式把对象的行为封装在不同状态的对象中,对象的行为随着内部状态的改变而改变,状态改变时,对应的行为也会随之转移到另一种状态的实现上。这样,状态和行为使用不同的具体状态对象来表示,而不是通过多个条件判断语句来控制。

为什么要使用状态模式

  1. 减少条件分支:状态模式通过把复杂的状态逻辑分散到各个状态对象中,减少了条件语句的复杂性。
  2. 增强代码组织:每个状态可以被组织在独立的类中,提高了代码的模块化。
  3. 易于扩展:新增状态或改变状态的行为不需要修改主体类或其他状态类,符合开闭原则。

使用状态模式需要注意的点

  1. 状态过多时的管理问题:如果状态非常多,系统中会有大量状态类,可能会导致管理和维护的复杂度增加。
  2. 状态与状态机耦合:虽然状态模式减少了依赖,但状态逻辑和状态机之间依然存在耦合。
  3. 性能问题:每次状态转换可能涉及创建新的状态对象,如果状态转换非常频繁,可能会影响性能。

工程的应用场景

  1. 工作流处理:如文档审批流程,根据不同阶段改变处理行为。
  2. 游戏开发:游戏角色根据不同状态(如正常、受伤、加速等)改变行为。
  3. UI控件状态:UI控件(如按钮、菜单)根据不同状态(如激活、禁用、悬停)显示不同行为。

示例代码及解释

假设我们正在开发一个游戏中的玩家角色,该角色根据不同的健康状态(正常、受伤、严重受伤)改变其行为。

首先定义状态接口和具体状态类:

#include <iostream>
#include <string>

class Player;

class State 
{
public:
    virtual void handle(Player* player) = 0;
    virtual ~State() {}
};

class NormalState : public State 
{
public:
    void handle(Player* player) override;
};

class InjuredState : public State 
{
public:
    void handle(Player* player) override;
};

class CriticalState : public State 
{
public:
    void handle(Player* player) override;
};

定义玩家类和状态改变逻辑:

class Player 
{
    State* currentState;
    int health;
public:
    Player() : currentState(new NormalState()), health(100) {}
    ~Player() { delete currentState; }

    void setHealth(int h) 
    {
        health = h;
        if (health > 70) 
        {
            changeState(new NormalState());
        } 
        else if (health > 30) 
        {
            changeState(new InjuredState());
        } 
        else 
        {
            changeState(new CriticalState());
        }
    }

    void changeState(State* state) 
    {
        delete currentState;
        currentState = state;
        currentState->handle(this);
    }

    void reportState() 
    {
        currentState->handle(this);
    }
};

void NormalState::handle(Player* player) 
{
    std::cout << "Player is in normal state." << std::endl;
}

void Injured

State::handle(Player* player) 
{
    std::cout << "Player is injured." << std::endl;
}

void CriticalState::handle(Player* player) 
{
    std::cout << "Player is in critical condition." << std::endl;
}

客户端代码:

int main() 
{
    Player player;
    player.reportState();  // Initially normal

    player.setHealth(50);  // Change to injured state
    player.reportState();

    player.setHealth(20);  // Change to critical state
    player.reportState();

    return 0;
}

输出代码运行结果

Player is in normal state.
Player is injured.
Player is injured.
Player is in critical condition.
Player is in critical condition.

这个示例演示了状态模式的应用,其中Player类的行为根据其健康状态的改变而改变。State类及其子类NormalState, InjuredState, CriticalState定义了在不同状态下的具体行为。这样的设计使得添加新的状态或改变现有状态的行为变得简单,且不需要修改Player类的内部实现。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++中,我们通常使用状态机来处理事件。监听模式可以用于实现状态机的事件监听器。下面是一个简单的示例代码: ```cpp #include <iostream> #include <vector> class EventListener { public: virtual void onEvent() = 0; }; class StateMachine { public: enum State { STATE_A, STATE_B, STATE_C }; StateMachine() : m_state(STATE_A) {} void addEventListener(EventListener* listener) { m_listeners.push_back(listener); } void triggerEvent() { for (auto listener : m_listeners) { listener->onEvent(); } switch (m_state) { case STATE_A: std::cout << "State A" << std::endl; m_state = STATE_B; break; case STATE_B: std::cout << "State B" << std::endl; m_state = STATE_C; break; case STATE_C: std::cout << "State C" << std::endl; m_state = STATE_A; break; } } private: State m_state; std::vector<EventListener*> m_listeners; }; class MyEventListener : public EventListener { public: virtual void onEvent() { std::cout << "Event triggered" << std::endl; } }; int main() { StateMachine stateMachine; MyEventListener eventListener; stateMachine.addEventListener(&eventListener); for (int i = 0; i < 3; ++i) { stateMachine.triggerEvent(); } return 0; } ``` 上述代码中,`EventListener` 是一个抽象类,其中只有一个纯虚函数 `onEvent`。`MyEventListener` 类继承自 `EventListener`,并实现了 `onEvent` 函数。`StateMachine` 类是一个状态机,其中 `triggerEvent` 函数可以触发状态机的事件。在 `triggerEvent` 函数中,我们首先遍历注册到状态机的监听器,并调用它们的 `onEvent` 函数。然后根据当前状态改变状态机的状态。`main` 函数中,我们创建了一个状态机和一个事件监听器,并将监听器注册到状态机中。最后,我们通过调用 `triggerEvent` 函数来触发状态机的事件,从而改变状态

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Warren++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值