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 清晰过渡
可复用性提升 ✅ 各状态类可在其他场景复用
相关推荐
程序喵大人44 分钟前
【C++入门】编译链接模型 - 01 一个 C++ 程序是怎样变成可执行文件的
开发语言·c++·编译链接模型
by209992 小时前
vector 的模拟实现:扩容与边界的详细阐述(下)
c++·经验分享·vector·动态数组
传奇开心果编程3 小时前
【SwiftUI提高练中学】第8课 网络层架构:拦截器、重试、缓存与离线优先
学习·macos·ui·ios·swiftui
传奇开心果编程4 小时前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
余额瞒着我当琳5 小时前
红黑树的实现--红黑树的概念、规则、效率、结构、旋转、查找、验证
数据结构·c++·算法
青少儿编程课堂5 小时前
AC自动机多模式串匹配精讲:校园关键词巡检实战解析
c++·python·算法·bfs·信息学竞赛
longlongzihan6 小时前
LeetCode 5. 最长回文子串:从暴力匹配到中心扩展的思维演进
c++·算法·leetcode
大圣编蚕6 小时前
Rancher证书轮换过期导致不能访问UI问题处理
ui·rancher
多弗朗皮卡丘6 小时前
C++继承
c++·继承
geovindu6 小时前
rust: Abstract Factory pattern
开发语言·后端·设计模式·rust·抽象工厂模式