C++ 设计模式《外卖骑手状态系统》

👨‍🎓 模式名称:状态模式(State)

👦 故事背景:

👦 小明在他的平台引入了外卖骑手系统,其中就需要及时记录和更新骑手的状态。骑手的状态分为:

  • 待接单
  • 配送中
  • 休息中

不同状态下,系统允许执行的操作不同:

状态 允许操作
待接单 可以接单
配送中 可以送达
休息中 什么都不能做

😵 不使用状态模式的痛点

小明一开始直接用了一个大 switch-case 写法:

cpp 复制代码
enum RiderState { Idle, Delivering, Resting };

class Rider {
public:
    RiderState state;

    void handle(const std::string& action) {
        if (state == Idle) {
            if (action == "接单") std::cout << "订单接下来了!" << std::endl;
            else std::cout << "当前不能 " << action << std::endl;
        } else if (state == Delivering) {
            if (action == "送达") std::cout << "订单已送达!" << std::endl;
            else std::cout << "当前不能 " << action << std::endl;
        } else if (state == Resting) {
            std::cout << "休息中,啥也不能干..." << std::endl;
        }
    }
};

问题来了:

  • 每次加新状态或行为,都要修改 handle 函数
  • 状态行为之间 耦合严重
  • 系统难以扩展和维护

✅ 使用状态模式进行优化

1️⃣ 状态接口(抽象状态类)
cpp 复制代码
class RiderContext;

class RiderState {
public:
    virtual void handle(RiderContext* context, const std::string& action) = 0;
    virtual std::string name() const = 0;
    virtual ~RiderState() {}
};
2️⃣ 具体状态类
cpp 复制代码
class IdleState : public RiderState {
public:
    void handle(RiderContext* context, const std::string& action) override;
    std::string name() const override { return "待接单"; }
};

class DeliveringState : public RiderState {
public:
    void handle(RiderContext* context, const std::string& action) override;
    std::string name() const override { return "配送中"; }
};

class RestingState : public RiderState {
public:
    void handle(RiderContext* context, const std::string& action) override;
    std::string name() const override { return "休息中"; }
};
3️⃣ 状态上下文类
cpp 复制代码
class RiderContext {
private:
    RiderState* state;
public:
    RiderContext(RiderState* init) : state(init) {}

    void setState(RiderState* s) {
        state = s;
        std::cout << "状态切换为:" << state->name() << std::endl;
    }

    void request(const std::string& action) {
        state->handle(this, action);
    }
};
4️⃣ 状态行为实现
cpp 复制代码
void IdleState::handle(RiderContext* context, const std::string& action) {
    if (action == "接单") {
        std::cout << "✅ 订单已接下!" << std::endl;
        static DeliveringState delivering;
        context->setState(&delivering);
    } else {
        std::cout << "❌ 当前状态不能执行:" << action << std::endl;
    }
}

void DeliveringState::handle(RiderContext* context, const std::string& action) {
    if (action == "送达") {
        std::cout << "✅ 外卖已送达!" << std::endl;
        static IdleState idle;
        context->setState(&idle);
    } else {
        std::cout << "❌ 当前状态不能执行:" << action << std::endl;
    }
}

void RestingState::handle(RiderContext* context, const std::string& action) {
    std::cout << "😴 休息中,不能进行任何操作..." << std::endl;
}
使用示例
cpp 复制代码
int main() {
    IdleState idle;
    RiderContext rider(&idle);

    rider.request("接单");
    rider.request("送达");

    static RestingState rest;
    rider.setState(&rest);
    rider.request("接单");
}

使用状态模式的优点

问题 是否解决
状态逻辑封装 ✅ 各状态类独立处理自己的逻辑
行为扩展方便 ✅ 新状态只需添加类,无需修改已有逻辑
状态切换明确 ✅ 使用 setState 清晰过渡
可复用性提升 ✅ 各状态类可在其他场景复用
相关推荐
青瓦梦滋6 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
CodeYp201911 小时前
第15讲:二叉搜索树
开发语言·c++·二叉搜索树
pipixia2003312 小时前
C++继承面试四连问:内存叠加、私有继承、sizeof、权限重映射
c++·面试·嵌入式·继承·面向对象·对象模型
昭昭日月明12 小时前
AI 时代的《重构》
设计模式·架构
牵猫散步的鱼儿14 小时前
C++ 内存分区
c++
choumin15 小时前
C++ 标准容器为什么不能存引用
c++·容器·引用类型
谙弆悕博士15 小时前
用 C 写了个 Windows 聊天室,踩了几个多线程和控制台的坑
c语言·开发语言·c++·windows·网络编程·聊天室
stolentime16 小时前
CF2277E Tree Guessing题解
c++·算法·贪心算法·交互·ad-hoc
syagain_zsx17 小时前
ODB 与 MySQL:C++ 里的 ORM 实践(类即表、事务铁律与查询封装)
开发语言·数据库·c++·mysql·工具库·1024程序员节
小鱼仙官17 小时前
使用Qt封装C/C++ 动态库 用于第三方调用
c语言·c++·qt