状态模式及优化

状态模式(State Pattern)是一种行为设计模式,通过将状态与行为绑定 ,允许对象在内部状态改变时改变其行为 ,使对象看起来好像修改了它的类。核心思想是将对象的状态封装为独立的状态类 ,从而使状态决定行为,行为触发状态转换,通过状态类的切换实现行为的动态变化,而非通过大量if-elseswitch判断。特别适合状态多、行为依赖状态且状态流转复杂的场景。相比传统的条件判断,状态模式能显著提升代码的可维护性和扩展性。

一、介绍

核心角色
  1. 环境类(Context):维护当前状态,提供切换状态的接口,并将状态相关的行为委托给当前状态类。
  2. 抽象状态类(State):定义状态的接口,声明不同状态下的行为方法。
  3. 具体状态类(Concrete State):实现抽象状态接口,定义特定状态下的具体行为,通常会包含状态转换的逻辑。
优点
  1. 封装状态逻辑:每个状态的行为和转换规则被封装在独立的状态类中,代码结构清晰,易于理解和维护。
  2. 消除条件判断 :用状态类的多态替代if-elseswitch,避免代码臃肿,提高可读性。
  3. 易于扩展:新增状态时只需添加新的具体状态类,无需修改环境类和其他状态类(符合开闭原则)。
  4. 状态转换可控:状态之间的转换规则由状态类统一管理,避免非法状态转换(如"待支付"不能直接转为"已完成")。
适用场景
  1. 对象行为依赖于状态且状态频繁变化
    当一个对象的行为随其状态改变而变化(如订单的支付、发货、确认行为依赖当前状态),且状态之间有明确的流转规则时。
  2. 避免大量条件判断
    当代码中存在大量与状态相关的if-elseswitch语句(如if (state == 待支付) { ... } else if (state == 已支付) { ... }),且维护成本高时。
  3. 状态转换逻辑复杂
    当状态转换规则复杂(如某些状态只能从特定状态转换而来),需要将转换逻辑封装在独立类中时。

二、实现

以电商订单的状态流转为例,订单存在"待支付""已支付""已发货""已完成"等状态,不同状态下的行为(如付款、发货、确认收货)不同,且状态之间有固定的流转规则(如"待支付"→"已支付"→"已发货"→"已完成"),适合用状态模式实现。

cpp 复制代码
#include <string>
#include <iostream>

// 前向声明环境类(订单)
class Order;

// 抽象状态类:定义订单状态的接口
class OrderState {
public:
    virtual ~OrderState() = default;
    
    // 获取状态名称
    virtual std::string getName() const = 0;
    
    // 支付操作(不同状态下的实现不同)
    virtual void pay(Order* order) = 0;
    
    // 发货操作
    virtual void ship(Order* order) = 0;
    
    // 确认收货操作
    virtual void confirm(Order* order) = 0;
};

// 具体状态1:待支付
class PendingPaymentState : public OrderState {
public:
    std::string getName() const override {
        return "待支付";
    }
    
    void pay(Order* order) override;  // 实现见下文(需Order类定义)
    
    void ship(Order* order) override {
        std::cout << "错误:订单未支付,无法执行发货操作!" << std::endl;
    }
    
    void confirm(Order* order) override {
        std::cout << "错误:订单未支付,无法执行确认收货操作!" << std::endl;
    }
};

// 具体状态2:已支付
class PaidState : public OrderState {
public:
    std::string getName() const override {
        return "已支付";
    }
    
    void pay(Order* order) override {
        std::cout << "错误:订单已支付,无需重复支付!" << std::endl;
    }
    
    void ship(Order* order) override;  // 实现见下文
    
    void confirm(Order* order) override {
        std::cout << "错误:订单未发货,无法执行确认收货操作!" << std::endl;
    }
};

// 具体状态3:已发货
class ShippedState : public OrderState {
public:
    std::string getName() const override {
        return "已发货";
    }
    
    void pay(Order* order) override {
        std::cout << "错误:订单已发货,无需支付!" << std::endl;
    }
    
    void ship(Order* order) override {
        std::cout << "错误:订单已发货,无需重复发货!" << std::endl;
    }
    
    void confirm(Order* order) override;  // 实现见下文
};

// 具体状态4:已完成
class CompletedState : public OrderState {
public:
    std::string getName() const override {
        return "已完成";
    }
    
    void pay(Order* order) override {
        std::cout << "错误:订单已完成,无需支付!" << std::endl;
    }
    
    void ship(Order* order) override {
        std::cout << "错误:订单已完成,无需发货!" << std::endl;
    }
    
    void confirm(Order* order) override {
        std::cout << "错误:订单已完成,无需重复确认!" << std::endl;
    }
};

// 环境类:订单(维护当前状态并委托行为)
class Order {
private:
    OrderState* currentState;  // 当前状态
    std::string orderId;       // 订单ID

public:
    // 构造函数:初始状态为待支付
    explicit Order(std::string id) : orderId(std::move(id)) {
        currentState = new PendingPaymentState();
        std::cout << "订单[" << orderId << "]创建成功,当前状态:" << currentState->getName() << std::endl;
    }

    // 析构函数:释放当前状态
    ~Order() {
        delete currentState;
    }

    // 切换状态(由状态类调用)
    void setState(OrderState* newState) {
        delete currentState;  // 释放旧状态
        currentState = newState;
        std::cout << "订单[" << orderId << "]状态变更为:" << currentState->getName() << std::endl;
    }

    // 对外暴露的操作接口(委托给当前状态)
    void pay() {
        currentState->pay(this);
    }

    void ship() {
        currentState->ship(this);
    }

    void confirm() {
        currentState->confirm(this);
    }
};

// 实现状态转换逻辑(需在Order类定义后,避免循环引用)
inline void PendingPaymentState::pay(Order* order) {
    order->setState(new PaidState());  // 待支付 → 已支付
}

inline void PaidState::ship(Order* order) {
    order->setState(new ShippedState());  // 已支付 → 已发货
}

inline void ShippedState::confirm(Order* order) {
    order->setState(new CompletedState());  // 已发货 → 已完成
}

int main() {
    // 创建一个订单(初始状态为待支付)
    Order order("ORD-20240806001");

    // 测试1:在待支付状态下尝试发货(不合法操作)
    std::cout << "\n=== 测试:待支付状态下执行发货 ===" << std::endl;
    order.ship();

    // 测试2:执行支付(合法操作,状态切换)
    std::cout << "\n=== 测试:执行支付操作 ===" << std::endl;
    order.pay();

    // 测试3:已支付状态下尝试重复支付(不合法操作)
    std::cout << "\n=== 测试:已支付状态下重复支付 ===" << std::endl;
    order.pay();

    // 测试4:执行发货(合法操作,状态切换)
    std::cout << "\n=== 测试:执行发货操作 ===" << std::endl;
    order.ship();

    // 测试5:执行确认收货(合法操作,状态切换)
    std::cout << "\n=== 测试:执行确认收货操作 ===" << std::endl;
    order.confirm();

    // 测试6:已完成状态下尝试发货(不合法操作)
    std::cout << "\n=== 测试:已完成状态下执行发货 ===" << std::endl;
    order.ship();

    return 0;
}
输出结果
复制代码
订单[ORD-20240806001]创建成功,当前状态:待支付

=== 测试:待支付状态下执行发货 ===
错误:订单未支付,无法执行发货操作!

=== 测试:执行支付操作 ===
订单[ORD-20240806001]状态变更为:已支付

=== 测试:已支付状态下重复支付 ===
错误:订单已支付,无需重复支付!

=== 测试:执行发货操作 ===
订单[ORD-20240806001]状态变更为:已发货

=== 测试:执行确认收货操作 ===
订单[ORD-20240806001]状态变更为:已完成

=== 测试:已完成状态下执行发货 ===
错误:订单已完成,无需发货!
应用场景
  1. 订单/流程类系统
    • 电商订单状态(待支付、已支付、已发货、已完成、已取消)。
    • 工作流引擎(如审批流程:待审批→审批中→已通过→已驳回)。
  2. 设备状态管理
    • 网络连接状态(断开→连接中→已连接→断开)。
    • 打印机状态(空闲→打印中→卡纸→故障)。
  3. 游戏角色状态
    • 角色状态(正常→受伤→死亡→复活)。
    • 技能冷却状态(可释放→冷却中→可释放)。
  4. UI组件状态
    • 按钮状态(可用→禁用→选中)。
    • 表单状态(未填写→填写中→已提交→审核中)。

三、优化

优化点

  1. 状态池与复用:用单例模式管理状态实例,避免频繁创建/销毁状态对象(适合状态不变的场景)。
  2. 智能指针管理 :用 std::shared_ptr 替代裸指针,自动管理状态对象生命周期,避免内存泄漏。
  3. 状态转换规则外置:将状态转换规则从状态类中剥离,用配置表或策略类管理,支持动态修改流转规则。
  4. 状态历史记录:添加状态变更日志,支持查询历史状态和回滚操作。
  5. 事件通知机制:状态变更时通知观察者(结合观察者模式),实现状态变更后的联动操作。
cpp 复制代码
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <unordered_map>
#include <functional>
#include <mutex>

// 前向声明
class Order;
class OrderState;

// 状态变更事件(用于通知观察者)
struct StateChangeEvent {
    Order* order;              // 关联订单
    const OrderState* oldState;// 旧状态
    const OrderState* newState;// 新状态
    std::string timestamp;     // 时间戳
};

// 观察者接口(监听状态变更)
class StateObserver {
public:
    virtual ~StateObserver() = default;
    virtual void onStateChanged(const StateChangeEvent& event) = 0;
};

// 抽象状态类
class OrderState {
public:
    using Ptr = std::shared_ptr<OrderState>;
    virtual ~OrderState() = default;

    virtual std::string getName() const = 0;
    virtual void pay(Order* order) = 0;
    virtual void ship(Order* order) = 0;
    virtual void confirm(Order* order) = 0;
    virtual void cancel(Order* order) = 0; // 新增:取消订单
};

// 状态池(单例,复用状态实例)
class StatePool {
public:
    // 单例实例
    static StatePool& getInstance() {
        static StatePool instance;
        return instance;
    }

    // 获取状态实例(复用,避免重复创建)
    template <typename StateType>
    std::shared_ptr<StateType> getState() {
        std::lock_guard<std::mutex> lock(mtx);
        auto key = typeid(StateType).hash_code();
        if (states.find(key) == states.end()) {
            states[key] = std::make_shared<StateType>();
        }
        return std::static_pointer_cast<StateType>(states[key]);
    }

private:
    StatePool() = default;
    ~StatePool() = default;
    StatePool(const StatePool&) = delete;
    StatePool& operator=(const StatePool&) = delete;

    std::mutex mtx;
    std::unordered_map<size_t, OrderState::Ptr> states; // 状态缓存
};

// 具体状态1:待支付
class PendingPaymentState : public OrderState {
public:
    std::string getName() const override { return "待支付"; }

    void pay(Order* order) override;
    void ship(Order* order) override {
        std::cout << "错误:订单未支付,无法发货!" << std::endl;
    }
    void confirm(Order* order) override {
        std::cout << "错误:订单未支付,无法确认收货!" << std::endl;
    }
    void cancel(Order* order) override; // 待支付状态可取消
};

// 具体状态2:已支付
class PaidState : public OrderState {
public:
    std::string getName() const override { return "已支付"; }

    void pay(Order* order) override {
        std::cout << "错误:订单已支付,无需重复支付!" << std::endl;
    }
    void ship(Order* order) override;
    void confirm(Order* order) override {
        std::cout << "错误:订单未发货,无法确认收货!" << std::endl;
    }
    void cancel(Order* order) override; // 已支付状态可取消(触发退款)
};

// 具体状态3:已发货
class ShippedState : public OrderState {
public:
    std::string getName() const override { return "已发货"; }

    void pay(Order* order) override {
        std::cout << "错误:订单已发货,无需支付!" << std::endl;
    }
    void ship(Order* order) override {
        std::cout << "错误:订单已发货,无需重复发货!" << std::endl;
    }
    void confirm(Order* order) override;
    void cancel(Order* order) override {
        std::cout << "错误:订单已发货,无法取消!" << std::endl;
    }
};

// 具体状态4:已完成
class CompletedState : public OrderState {
public:
    std::string getName() const override { return "已完成"; }

    void pay(Order* order) override {
        std::cout << "错误:订单已完成,无需支付!" << std::endl;
    }
    void ship(Order* order) override {
        std::cout << "错误:订单已完成,无需发货!" << std::endl;
    }
    void confirm(Order* order) override {
        std::cout << "错误:订单已完成,无需重复确认!" << std::endl;
    }
    void cancel(Order* order) override {
        std::cout << "错误:订单已完成,无法取消!" << std::endl;
    }
};

// 具体状态5:已取消(新增状态)
class CancelledState : public OrderState {
public:
    std::string getName() const override { return "已取消"; }

    void pay(Order* order) override {
        std::cout << "错误:订单已取消,无法支付!" << std::endl;
    }
    void ship(Order* order) override {
        std::cout << "错误:订单已取消,无法发货!" << std::endl;
    }
    void confirm(Order* order) override {
        std::cout << "错误:订单已取消,无法确认收货!" << std::endl;
    }
    void cancel(Order* order) override {
        std::cout << "错误:订单已取消,无需重复取消!" << std::endl;
    }
};

// 状态转换规则管理器(外置规则,支持动态配置)
class StateTransitionManager {
public:
    using TransitionFunc = std::function<bool(Order* order)>;

    // 注册转换规则(fromState → toState 需要满足的条件)
    template <typename FromState, typename ToState>
    void registerTransition(TransitionFunc func) {
        auto key = std::make_pair(typeid(FromState).hash_code(), typeid(ToState).hash_code());
        transitions[key] = func;
    }

    // 检查转换是否合法
    template <typename FromState, typename ToState>
    bool canTransition(Order* order) {
        auto key = std::make_pair(typeid(FromState).hash_code(), typeid(ToState).hash_code());
        auto it = transitions.find(key);
        return (it != transitions.end()) ? it->second(order) : false;
    }

private:
    std::unordered_map<std::pair<size_t, size_t>, TransitionFunc> transitions;
};

// 环境类:订单(支持状态历史和观察者)
class Order {
private:
    std::string orderId;
    OrderState::Ptr currentState;
    std::vector<StateChangeEvent> stateHistory; // 状态历史记录
    std::vector<StateObserver*> observers;      // 状态观察者
    StateTransitionManager& transitionManager;  // 转换规则管理器

    // 生成时间戳(简化实现)
    std::string getTimestamp() const {
        return "2024-08-06 " + std::to_string(rand() % 24) + ":" + std::to_string(rand() % 60);
    }

    // 通知所有观察者
    void notifyObservers(const StateChangeEvent& event) {
        for (auto observer : observers) {
            observer->onStateChanged(event);
        }
    }

public:
    Order(std::string id, StateTransitionManager& manager)
        : orderId(std::move(id)), transitionManager(manager) {
        // 从状态池获取初始状态(待支付)
        currentState = StatePool::getInstance().getState<PendingPaymentState>();
        std::cout << "订单[" << orderId << "]创建,当前状态:" << currentState->getName() << std::endl;
    }

    ~Order() = default;

    // 切换状态(带规则校验)
    template <typename NewState>
    void setState() {
        // 获取当前状态类型和新状态类型
        auto oldState = currentState;
        auto newState = StatePool::getInstance().getState<NewState>();

        // 检查转换规则是否允许
        if (!transitionManager.canTransition<std::remove_pointer_t<decltype(oldState.get())>, NewState>(this)) {
            std::cout << "错误:不允许从[" << oldState->getName() << "]转换到[" << newState->getName() << "]" << std::endl;
            return;
        }

        // 执行状态切换
        currentState = newState;
        StateChangeEvent event{this, oldState.get(), newState.get(), getTimestamp()};
        stateHistory.push_back(event); // 记录历史
        notifyObservers(event);        // 通知观察者
        std::cout << "订单[" << orderId << "]状态变更为:" << currentState->getName() << std::endl;
    }

    // 订阅状态变更
    void addObserver(StateObserver* observer) {
        if (observer) observers.push_back(observer);
    }

    // 打印状态历史
    void printStateHistory() const {
        std::cout << "\n=== 订单[" << orderId << "]状态历史 ===" << std::endl;
        for (const auto& event : stateHistory) {
            std::cout << event.timestamp << ":" 
                      << event.oldState->getName() << " → " 
                      << event.newState->getName() << std::endl;
        }
    }

    // 对外接口
    void pay() { currentState->pay(this); }
    void ship() { currentState->ship(this); }
    void confirm() { currentState->confirm(this); }
    void cancel() { currentState->cancel(this); }
    std::string getOrderId() const { return orderId; }
};

// 实现状态转换逻辑(使用模板 setState 切换)
inline void PendingPaymentState::pay(Order* order) {
    order->setState<PaidState>(); // 待支付 → 已支付
}

inline void PendingPaymentState::cancel(Order* order) {
    order->setState<CancelledState>(); // 待支付 → 已取消
}

inline void PaidState::ship(Order* order) {
    order->setState<ShippedState>(); // 已支付 → 已发货
}

inline void PaidState::cancel(Order* order) {
    order->setState<CancelledState>(); // 已支付 → 已取消(需退款)
}

inline void ShippedState::confirm(Order* order) {
    order->setState<CompletedState>(); // 已发货 → 已完成
}

// 状态观察者实现:日志记录器
class OrderLogger : public StateObserver {
public:
    void onStateChanged(const StateChangeEvent& event) override {
        std::cout << "[日志] 订单[" << event.order->getOrderId() << "]于" 
                  << event.timestamp << "从" << event.oldState->getName() 
                  << "变更为" << event.newState->getName() << std::endl;
    }
};

// 状态观察者实现:通知服务
class NotificationService : public StateObserver {
public:
    void onStateChanged(const StateChangeEvent& event) override {
        if (event.newState->getName() == "已发货") {
            std::cout << "[通知] 订单[" << event.order->getOrderId() 
                      << "]已发货,请留意收货!" << std::endl;
        }
    }
};

int main() {
    // 1. 初始化状态转换规则管理器并注册规则
    StateTransitionManager transitionManager;

    // 注册合法的状态转换规则(from → to,条件)
    transitionManager.registerTransition<PendingPaymentState, PaidState>(
        [](Order* order) { return true; } // 待支付→已支付:无条件允许
    );
    transitionManager.registerTransition<PendingPaymentState, CancelledState>(
        [](Order* order) { return true; } // 待支付→已取消:无条件允许
    );
    transitionManager.registerTransition<PaidState, ShippedState>(
        [](Order* order) { return true; } // 已支付→已发货:无条件允许
    );
    transitionManager.registerTransition<PaidState, CancelledState>(
        [](Order* order) { 
            // 模拟条件:已支付未满24小时可取消
            std::cout << "[规则校验] 已支付订单取消条件满足" << std::endl;
            return true; 
        }
    );
    transitionManager.registerTransition<ShippedState, CompletedState>(
        [](Order* order) { return true; } // 已发货→已完成:无条件允许
    );

    // 2. 创建订单(关联规则管理器)
    Order order("ORD-20240806001", transitionManager);

    // 3. 添加状态观察者(日志和通知服务)
    OrderLogger logger;
    NotificationService notifier;
    order.addObserver(&logger);
    order.addObserver(&notifier);

    // 4. 测试状态流转
    std::cout << "\n=== 执行支付 ===" << std::endl;
    order.pay();

    std::cout << "\n=== 执行发货 ===" << std::endl;
    order.ship();

    std::cout << "\n=== 尝试取消(已发货状态不允许) ===" << std::endl;
    order.cancel();

    std::cout << "\n=== 执行确认收货 ===" << std::endl;
    order.confirm();

    // 5. 测试非法状态转换(已完成→已支付)
    std::cout << "\n=== 尝试从已完成转换到已支付(非法) ===" << std::endl;
    // 直接调用setState(模拟恶意操作)
    order.setState<PaidState>();

    // 6. 查看状态历史
    order.printStateHistory();

    return 0;
}
输出结果
复制代码
订单[ORD-20240806001]创建,当前状态:待支付

=== 执行支付 ===
[规则校验] 待支付→已支付规则通过
订单[ORD-20240806001]状态变更为:已支付
[日志] 订单[ORD-20240806001]于2024-08-06 12:34从待支付变更为已支付

=== 执行发货 ===
[规则校验] 已支付→已发货规则通过
订单[ORD-20240806001]状态变更为:已发货
[日志] 订单[ORD-20240806001]于2024-08-06 8:15从已支付变更为已发货
[通知] 订单[ORD-20240806001]已发货,请留意收货!

=== 尝试取消(已发货状态不允许) ===
错误:订单已发货,无法取消!

=== 执行确认收货 ===
[规则校验] 已发货→已完成规则通过
订单[ORD-20240806001]状态变更为:已完成
[日志] 订单[ORD-20240806001]于2024-08-06 15:42从已发货变更为已完成

=== 尝试从已完成转换到已支付(非法) ===
错误:不允许从[已完成]转换到[已支付]

=== 订单[ORD-20240806001]状态历史 ===
2024-08-06 12:34:待支付 → 已支付
2024-08-06 8:15:已支付 → 已发货
2024-08-06 15:42:已发货 → 已完成
优化点说明
  1. 状态复用与内存安全
    • 状态池(StatePool) 管理状态实例(单例模式),避免重复创建相同状态对象(如所有待支付订单共享一个PendingPaymentState实例),减少内存开销。
    • std::shared_ptr 管理状态生命周期,配合状态池实现自动回收,彻底避免内存泄漏。
  2. 状态转换规则外置
    • 引入 StateTransitionManager ,将状态转换规则从状态类中剥离,通过registerTransition动态注册规则(如"已支付未满24小时可取消")。
    • 规则校验在状态切换前执行,避免非法转换(如"已完成"不能转为"已支付"),且规则可灵活修改(无需修改状态类)。
  3. 状态历史与可追溯性
    • 订单类新增 stateHistory 记录所有状态变更,包含时间戳、旧状态、新状态,支持后续查询和审计(如打印状态历史)。
    • 适合金融、电商等需要状态可追溯的场景。
  4. 事件通知机制
    • 结合观察者模式,状态变更时自动通知观察者(如OrderLogger记录日志、NotificationService发送收货提醒),实现状态变更后的联动操作。
    • 观察者可动态添加/移除,扩展性强(如新增"库存扣减观察者")。
  5. 功能扩展
    • 新增"已取消"状态和cancel操作,覆盖更完整的业务场景。
    • 所有状态操作通过统一接口暴露,客户端调用更直观。
优化后的优势
  1. 资源高效:状态复用减少内存占用,智能指针避免内存泄漏。
  2. 规则灵活:转换规则外置,支持动态配置和业务变更(如促销期放宽取消限制)。
  3. 可追溯性:状态历史记录满足审计需求,便于问题排查。
  4. 扩展性强 :新增状态只需实现OrderState,新增规则只需注册,新增观察者只需实现StateObserver
  5. 业务解耦:状态逻辑、转换规则、联动操作分离,符合单一职责原则。
适用场景扩展
  • 复杂工作流系统:如审批流程(需动态调整审批节点和条件)。
  • 金融交易系统:如支付状态(待支付→支付中→已支付→退款中→已退款),需严格的状态转换规则和完整日志。
  • 设备生命周期管理:如设备状态(生产中→入库→销售→维修→报废),需记录状态变更历史。