目录

状态变化_State


状态变化”模式

在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?“状态变化“模式为这一问题提供了一种解决方案。

典型模式

  • state
  • memento

1 state 状态模式

1.1 模式动机

在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。

如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?

1.2 模式定义

允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。

1.3 模式示例代码

#include <iostream>
#include <string>

// 前向声明
class Order;

// 抽象状态类:订单状态
class OrderState {
public:
    virtual void process(Order* order) = 0;
};

// 具体状态类:待付款状态
class PendingPaymentState : public OrderState {
public:
    void process(Order* order);
};

// 具体状态类:已发货状态
class ShippedState : public OrderState {
public:
    void process(Order* order);
};

// 具体状态类:已完成状态
class CompletedState : public OrderState {
public:
    void process(Order* order);
};

// 上下文类:订单
class Order {
public:
    Order() : currentState(nullptr) {}

    void setState(OrderState* state) {
        currentState = state;
    }

    void process() {
        if (currentState != nullptr) {
            currentState->process(this);
        }
    }

private:
    OrderState* currentState;
};

void PendingPaymentState::process(Order* order) {
    std::cout << "订单状态:待付款" << std::endl;
    // 处理待付款状态的逻辑
    // ...
    // 状态转换
    order->setState(new ShippedState());
    delete this;
}

void ShippedState::process(Order* order) {
    std::cout << "订单状态:已发货" << std::endl;
    // 处理已发货状态的逻辑
    // ...
    // 状态转换
    order->setState(new CompletedState());
    delete this;
}

void CompletedState::process(Order* order) {
    std::cout << "订单状态:已完成" << std::endl;
    // 处理已完成状态的逻辑
    // ...
    delete this;
}

int main() {
    Order order;

    // 处理订单状态
    order.process();

    // 处理订单状态
    order.process();

    // 处理订单状态
    order.process();

    return 0;
}

2 要点总结

State 模式将所有与一个特定状态相关的行为都放入一个 State 的子类对象中,在对象状态切换时,切换相应的对象;但同时维持 State 的接口,这样实现了具体操作与状态转换之间的解耦。

为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的一—即要么彻底转换过来,要么不转换。

如果 State 对象没有实例变量,那么各个上下文可以共享同一个 State 对象,从而节省对象开销。