在很多业务系统中,你一定遇到过这种代码:
python
def handle(order):
if order.status == "created":
...
elif order.status == "paid":
...
elif order.status == "shipped":
...
elif order.status == "completed":
...
刚开始还好,但随着业务发展:
- 状态越来越多
- 状态之间有流转规则
- 每个状态逻辑越来越复杂
代码会变成:
巨型 if/else 地狱
这正是 状态模式(State) 要解决的问题。
一、状态模式解决什么问题?
一句话:
允许对象在内部状态改变时改变它的行为,看起来像改变了对象本身。
关键词:
- 状态驱动行为
- 消除 if/else
- 状态流转
- 行为封装
二、一个典型场景:订单状态流转
订单常见状态:
text
创建 → 已支付 → 已发货 → 已完成
不同状态下:
- 能执行的操作不同
- 行为逻辑不同
例如:
| 状态 | 可操作 |
|---|---|
| 创建 | 支付、取消 |
| 已支付 | 发货 |
| 已发货 | 收货 |
| 已完成 | 无 |
如果用 if/else:
- 状态判断到处都是
- 修改一个状态影响全局
三、状态模式的核心思想
把"状态"变成对象。
结构:
Context ---> State
|
-------------------
| | |
StateA StateB StateC
核心:
- 每个状态一个类
- 状态负责行为
- 状态可以切换
四、Python 实现状态模式
1️⃣ 定义状态接口
python
from abc import ABC, abstractmethod
class OrderState(ABC):
@abstractmethod
def handle(self, order):
pass
2️⃣ 具体状态类
python
class CreatedState(OrderState):
def handle(self, order):
print("订单创建,可以支付")
order.set_state(PaidState())
class PaidState(OrderState):
def handle(self, order):
print("已支付,准备发货")
order.set_state(ShippedState())
class ShippedState(OrderState):
def handle(self, order):
print("已发货,等待收货")
order.set_state(CompletedState())
class CompletedState(OrderState):
def handle(self, order):
print("订单已完成")
3️⃣ 上下文(Context)
python
class Order:
def __init__(self):
self.state = CreatedState()
def set_state(self, state):
self.state = state
def process(self):
self.state.handle(self)
4️⃣ 使用方式
python
order = Order()
order.process()
order.process()
order.process()
order.process()
输出:
订单创建,可以支付
已支付,准备发货
已发货,等待收货
订单已完成
五、状态模式的核心价值
状态模式本质是:
把"状态判断逻辑"分散到各个状态类中。
它解决的是:
- if/else 过多
- 状态逻辑复杂
- 状态流转难维护
六、状态模式 vs 策略模式
很多人会混淆。
它们结构很像,但核心不同:
| 对比点 | 状态模式 | 策略模式 |
|---|---|---|
| 目的 | 状态驱动行为 | 算法替换 |
| 是否自动切换 | 是 | 否 |
| 是否依赖上下文 | 强 | 弱 |
一句话:
策略是"你选哪个",
状态是"系统帮你切换"。
七、更真实一点的写法(带行为约束)
在真实系统中,不同状态允许的操作不同:
python
class CreatedState(OrderState):
def pay(self, order):
print("支付成功")
order.set_state(PaidState())
def cancel(self, order):
print("订单取消")
python
class PaidState(OrderState):
def ship(self, order):
print("发货")
order.set_state(ShippedState())
调用:
python
order.state.pay(order)
order.state.ship(order)
每个状态只暴露允许的操作。
八、真实项目中的应用
非常常见:
1️⃣ 订单系统
状态流转:
- 创建 → 支付 → 发货 → 完成
2️⃣ 工作流引擎
审批流程:
- 待审批 → 审批中 → 已通过 → 已拒绝
3️⃣ 游戏开发
角色状态:
- 待机
- 攻击
- 防御
- 死亡
4️⃣ 连接状态
TCP 状态机:
- LISTEN
- SYN_SENT
- ESTABLISHED
九、状态模式优缺点
✅ 优点
- 消除大量 if/else
- 状态逻辑清晰
- 易于扩展新状态
- 符合开闭原则
❌ 缺点
- 类数量增加
- 结构变复杂
- 状态过多时难管理
十、什么时候使用状态模式?
适合:
- 状态很多
- 状态行为不同
- 状态有明确流转
不适合:
- 状态很少
- 逻辑简单
十一、一句话总结
状态模式的本质是:
把"状态"变成对象,让状态自己决定行为。
换句话说:
不要用 if/else 判断状态,让状态自己说该干什么。