状态模式详解与真实场景案例(Java实现)

打印 上一主题 下一主题

主题 1733|帖子 1733|积分 5199

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
模式界说

状态模式(State Pattern) 允许对象在其内部状态改变时改变它的举动,使对象看起来像是修改了它的类。属于举动型设计模式,焦点思想是将状态抽象为独立对象,差异状态下举动封装在差异状态类中。
解决的问题

消除庞大的条件分支

避免对象在差异状态下使用大量if-else或switch-case判断状态
状态转换逻辑清晰化

将状态转移规则封装在状态对象中
进步扩展性

新增状态时只需添加新状态类,无需修改现有代码
真实场景案例:电商订单状态流转

需求配景

电商订单存在多种状态:
待支付 → 已支付 → 已发货 → 已收货 → 已完成
每个状态下可实验的操作差异:
待支付状态:允许支付、取消订单
已支付状态:允许发货、退款
已发货状态:允许确认收货
已收货状态:允许完成订单
已完成/已取消状态:不可再操作
代码实现

1. 界说状态接口

  1. // 订单状态接口
  2. public interface OrderState {
  3.     void pay(OrderContext context);      // 支付
  4.     void cancel(OrderContext context);   // 取消
  5.     void ship(OrderContext context);     // 发货
  6.     void receive(OrderContext context);  // 收货
  7.     void complete(OrderContext context); // 完成
  8. }
复制代码
2. 实现详细状态类

待支付状态
  1. public class UnpaidState implements OrderState {
  2.     @Override
  3.     public void pay(OrderContext context) {
  4.         System.out.println("支付成功");
  5.         context.setState(new PaidState());
  6.     }
  7.     @Override
  8.     public void cancel(OrderContext context) {
  9.         System.out.println("订单已取消");
  10.         context.setState(new CancelledState());
  11.     }
  12.     // 其他操作不支持
  13.     @Override
  14.     public void ship(OrderContext context) {
  15.         throw new UnsupportedOperationException("待支付状态不能发货");
  16.     }
  17.     @Override
  18.     public void receive(OrderContext context) {
  19.         throw new UnsupportedOperationException("非法操作");
  20.     }
  21.     @Override
  22.     public void complete(OrderContext context) {
  23.         throw new UnsupportedOperationException("非法操作");
  24.     }
  25. }
复制代码
已支付状态
  1. public class PaidState implements OrderState {
  2.     @Override
  3.     public void ship(OrderContext context) {
  4.         System.out.println("商品已发货");
  5.         context.setState(new ShippedState());
  6.     }
  7.     @Override
  8.     public void cancel(OrderContext context) {
  9.         System.out.println("发起退款流程");
  10.         context.setState(new CancelledState());
  11.     }
  12.     // 其他操作处理
  13.     @Override
  14.     public void pay(OrderContext context) {
  15.         throw new UnsupportedOperationException("已支付状态不能重复支付");
  16.     }
  17.     // ... 类似处理其他不支持操作
  18. }
复制代码
其他状态类(已发货、已收货、已完成、已取消)实现方式类似,此处省略。
3. 界说订单上下文

  1. public class OrderContext {
  2.     private OrderState currentState;
  3.     public OrderContext() {
  4.         this.currentState = new UnpaidState(); // 初始状态
  5.     }
  6.     public void setState(OrderState state) {
  7.         this.currentState = state;
  8.     }
  9.     // 委托操作给当前状态
  10.     public void pay() { currentState.pay(this); }
  11.     public void cancel() { currentState.cancel(this); }
  12.     public void ship() { currentState.ship(this); }
  13.     public void receive() { currentState.receive(this); }
  14.     public void complete() { currentState.complete(this); }
  15. }
复制代码
4. 客户端使用

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         OrderContext order = new OrderContext();
  4.         
  5.         order.pay();       // 正常支付
  6.         order.ship();       // 正常发货
  7.         order.receive();    // 正常收货
  8.         order.complete();   // 完成订单
  9.         
  10.         try {
  11.             order.ship();   // 尝试非法操作
  12.         } catch (Exception e) {
  13.             System.out.println("操作失败: " + e.getMessage());
  14.         }
  15.     }
  16. }
复制代码
输出结果
复制
支付乐成
商品已发货
确认收货乐成
订单已完成
操作失败: 已完成状态不能发货
模式上风

上风传统条件分支实现状态模式实现可维护性修改状态逻辑需改动大量条件判断只需修改对应状态类可扩展性新增状态需修改所有相干方法新增状态类即可代码清晰度一个方法包罗所有状态逻辑每个状态逻辑独立封装单一职责违反单一职责原则每个状态类职责明确 实际应用场景

工作流引擎
审批流程中的差异状态(起草、审批中、已通过、被驳回)
游戏开发
脚色状态(站立、移动、攻击、死亡)
硬件控制
电梯运行状态(制止、运行、故障)
UI交互
按钮的差异状态(正常、禁用、悬停、点击)
通过状态模式,我们实现了:
✅ 消除复杂的条件判断
✅ 状态转换逻辑内聚到状态类中
✅ 符合开闭原则(新增状态无需修改现有代码)
✅ 更易维护的清晰代码布局
一句话总结

状态模式就是将状态都独立出来,将状态与实际业务解耦。相对于策略模式,状态与状态之间有接洽,策略与策略之间是独立的。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表