Java状态模式
状态模式允许对象在内部状态改变时改变行为,看起来像改变了类。
模式定义
意图:允许对象在内部状态改变时改变行为。
适用场景
- 对象行为取决于状态
- 状态转换逻辑复杂
- 需消除大量条件判断
模式结构
状态接口
Java
public interface State {
void handle(Context context);
}
具体状态
Java
public class StateA implements State {
@Override
public void handle(Context context) {
System.out.println("状态A处理");
context.setState(new StateB()); // 切换到状态B
}
}
public class StateB implements State {
@Override
public void handle(Context context) {
System.out.println("状态B处理");
context.setState(new StateC()); // 切换到状态C
}
}
public class StateC implements State {
@Override
public void handle(Context context) {
System.out.println("状态C处理");
context.setState(new StateA()); // 回到状态A
}
}
上下文类
Java
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle(this); // 当前状态处理请求
}
}
使用示例
Java
Context context = new Context(new StateA());
context.request(); // 状态A处理
context.request(); // 状态B处理
context.request(); // 状态C处理
context.request(); // 状态A处理(循环)
实际应用示例
订单状态
Java
public interface OrderState {
void pay(Order order);
void ship(Order order);
void deliver(Order order);
void cancel(Order order);
}
public class NewState implements OrderState {
@Override
public void pay(Order order) {
System.out.println("订单支付成功");
order.setState(new PaidState());
}
@Override
public void ship(Order order) {
throw new IllegalStateException("未支付,不能发货");
}
@Override
public void deliver(Order order) {
throw new IllegalStateException("未发货,不能确认收货");
}
@Override
public void cancel(Order order) {
System.out.println("订单已取消");
order.setState(new CancelledState());
}
}
public class PaidState implements OrderState {
@Override
public void pay(Order order) {
throw new IllegalStateException("已支付");
}
@Override
public void ship(Order order) {
System.out.println("订单已发货");
order.setState(new ShippedState());
}
@Override
public void deliver(Order order) {
throw new IllegalStateException("未发货");
}
@Override
public void cancel(Order order) {
System.out.println("申请退款");
order.setState(new CancelledState());
}
}
public class ShippedState implements OrderState {
@Override
public void pay(Order order) {
throw new IllegalStateException("已支付");
}
@Override
public void ship(Order order) {
throw new IllegalStateException("已发货");
}
@Override
public void deliver(Order order) {
System.out.println("订单已签收");
order.setState(new DeliveredState());
}
@Override
public void cancel(Order order) {
throw new IllegalStateException("已发货,不能取消");
}
}
public class Order {
private OrderState state;
public Order() {
this.state = new NewState();
}
public void setState(OrderState state) {
this.state = state;
}
public void pay() { state.pay(this); }
public void ship() { state.ship(this); }
public void deliver() { state.deliver(this); }
public void cancel() { state.cancel(this); }
}
状态转换图
text
新建 ──支付──→ 已支付 ──发货──→ 已发货 ──签收──→ 已签收
│ │
└取消──────→ 已取消
状态模式 vs 策略模式
| 特性 | 状态模式 | 策略模式 |
|---|---|---|
| 目的 | 状态切换 | 算法切换 |
| 切换方式 | 自动切换 | 客户端选择 |
| 状态数量 | 固定转换 | 无转换关系 |
| 状态感知 | 各状态知道其他状态 | 各策略独立 |
状态模式优点
- 消除大量条件判断
- 状态转换逻辑集中
- 新增状态容易
- 状态行为清晰分离
注意事项
状态过多时类数量增加
状态切换逻辑可放在Context或State中
避免循环状态导致无限循环
状态对象可共享,减少创建开销
要点总结
- 状态模式根据内部状态改变对象行为
- State接口定义状态行为
- Context持有当前状态,委托处理
- 状态自动切换,无需客户端干预
- 消除if-else判断,订单状态是典型应用
📝 发现内容有误?点击此处直接编辑