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 清晰过渡
可复用性提升 ✅ 各状态类可在其他场景复用
相关推荐
CoderCodingNo1 小时前
【GESP】C++三级真题 luogu-B4499, [GESP202603 三级] 二进制回文串
数据结构·c++·算法
hetao17338372 小时前
2026-04-09~12 hetao1733837 的刷题记录
c++·算法
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 136. 只出现一次的数字 | C++ 哈希表&异或基础解法
c++·算法·leetcode
汉克老师3 小时前
GESP2024年6月认证C++三级( 第二部分判断题(1-10))
c++·数组·位运算·补码·gesp三级·gesp3级
无限进步_4 小时前
【C++】只出现一次的数字 II:位运算的三种解法深度解析
数据结构·c++·ide·windows·git·算法·leetcode
小贾要学习4 小时前
【Linux】TCP网络通信编程
linux·服务器·网络·c++·网络协议·tcp/ip
哎嗨人生公众号5 小时前
手写求导公式,让轨迹优化性能飞升,150ms变成9ms
开发语言·c++·算法·机器人·自动驾驶
code_whiter5 小时前
C++6(模板)
开发语言·c++
一只旭宝5 小时前
【C++ 入门精讲1】初始化、const、引用、内联函数 | 超详细手写笔记(附完整代码)
开发语言·c++
旖-旎5 小时前
哈希表(字母异位次分组)(5)
数据结构·c++·算法·leetcode·哈希算法·散列表