状态变化_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 对象,从而节省对象开销。