经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式学习:2、状态模式实现订单状态流转
来源:cnblogs  作者:黄明基  时间:2025/3/7 9:10:18  对本文有异议

支付场景中的状态流转

在开发电商支付模块时,我们常遇到这样的状态流转需求:

  • 订单需要经历 待支付支付中支付成功/失败退款处理 的完整生命周期。
  • 不同状态下可执行的操作不同(例如只有支付成功才能退款)。
  • 状态转换需要触发附加操作(支付成功要发通知、更新库存)。

传统的 if-elseswitch 实现方式会导致:

  • 代码臃肿,维护困难
  • 状态转换逻辑分散
  • 新增状态需要修改大量现有代码

此时,状态模式(State Pattern)是这些问题的最佳解决方案。

状态模式核心思想

通过将状态抽象为独立类,实现两大关键特性:

  1. 行为状态化 :不同状态下相同的操作产生不同结果
  2. 转换自动化 :状态对象自行决定下一个状态

状态模式实现

  1. 状态接口设计
  1. // 订单状态抽象接口
  2. public interface IOrderState
  3. {
  4. void Process(OrderContext context);
  5. void Cancel(OrderContext context);
  6. void Refund(OrderContext context);
  7. }
  8. // 订单上下文(维护当前状态)
  9. public class OrderContext
  10. {
  11. private IOrderState _currentState;
  12. public string OrderId { get; } = Guid.NewGuid().ToString();
  13. public OrderContext(IOrderState initialState)
  14. {
  15. TransitionTo(initialState);
  16. }
  17. public void TransitionTo(IOrderState state)
  18. {
  19. Console.WriteLine($"订单状态变更:{_currentState?.GetType().Name} → {state.GetType().Name}");
  20. _currentState = state;
  21. }
  22. public void ProcessPayment() => _currentState.Process(this);
  23. public void CancelOrder() => _currentState.Cancel(this);
  24. public void RequestRefund() => _currentState.Refund(this);
  25. }
  1. 具体状态类实现
    待支付状态:
  1. public class PendingState : IOrderState
  2. {
  3. public void Process(OrderContext context)
  4. {
  5. Console.WriteLine("开始支付处理...");
  6. // 调用支付网关接口
  7. context.TransitionTo(new ProcessingState());
  8. }
  9. public void Cancel(OrderContext context)
  10. {
  11. Console.WriteLine("订单已取消");
  12. context.TransitionTo(new CanceledState());
  13. }
  14. public void Refund(OrderContext context)
  15. {
  16. Console.WriteLine("待支付订单不能退款");
  17. throw new InvalidOperationException("待支付订单不能退款");
  18. }
  19. }

支付中状态:

  1. public class ProcessingState : IOrderState
  2. {
  3. public void Process(OrderContext context)
  4. {
  5. Console.WriteLine("支付处理中...");
  6. context.TransitionTo(new PaidState());
  7. }
  8. public void Cancel(OrderContext context)
  9. {
  10. Console.WriteLine("支付处理中,不可取消订单...");
  11. throw new InvalidOperationException("支付处理中,不可取消订单...");
  12. }
  13. public void Refund(OrderContext context)
  14. {
  15. Console.WriteLine("支付未完成不能退款");
  16. throw new InvalidOperationException("支付未完成不能退款");
  17. }
  18. }

支付成功状态:

  1. public class PaidState : IOrderState
  2. {
  3. public void Process(OrderContext context)
  4. {
  5. Console.WriteLine("订单已完成支付");
  6. throw new InvalidOperationException("订单已完成支付");
  7. }
  8. public void Cancel(OrderContext context)
  9. {
  10. Console.WriteLine("已支付订单需走退款流程");
  11. throw new InvalidOperationException("已支付订单需走退款流程");
  12. }
  13. public void Refund(OrderContext context)
  14. {
  15. Console.WriteLine("发起退款申请...");
  16. // 调用退款接口
  17. context.TransitionTo(new RefundingState());
  18. }
  19. }

退款中状态:

  1. public class RefundingState : IOrderState
  2. {
  3. public void Process(OrderContext context)
  4. {
  5. Console.WriteLine("退款处理中...");
  6. context.TransitionTo(new RefundedState());
  7. }
  8. public void Cancel(OrderContext context)
  9. {
  10. Console.WriteLine("退款处理中,不可取消订单...");
  11. throw new InvalidOperationException("退款处理中,不可取消订单...");
  12. }
  13. public void Refund(OrderContext context)
  14. {
  15. Console.WriteLine("退款处理中,不可重复退款");
  16. throw new InvalidOperationException("退款处理中,不可重复退款");
  17. }
  18. }

退款完成状态:

  1. public class RefundedState : IOrderState
  2. {
  3. public void Process(OrderContext context)
  4. {
  5. Console.WriteLine("退款完成,订单已取消");
  6. throw new InvalidOperationException("退款完成,订单已取消");
  7. }
  8. public void Cancel(OrderContext context)
  9. {
  10. Console.WriteLine("订单已退款,无需取消");
  11. throw new InvalidOperationException("订单已退款,无需取消");
  12. }
  13. public void Refund(OrderContext context)
  14. {
  15. Console.WriteLine("订单已退款,无需退款");
  16. throw new InvalidOperationException("订单已退款,无需退款");
  17. }
  18. }

订单取消状态:

  1. public class CanceledState : IOrderState
  2. {
  3. public void Process(OrderContext context)
  4. {
  5. Console.WriteLine("订单已取消,无需支付");
  6. throw new InvalidOperationException("订单已取消,无需支付");
  7. }
  8. public void Cancel(OrderContext context)
  9. {
  10. Console.WriteLine("订单已取消,无需取消");
  11. throw new InvalidOperationException("订单已取消,无需取消");
  12. }
  13. public void Refund(OrderContext context)
  14. {
  15. Console.WriteLine("订单已取消,无需退款");
  16. throw new InvalidOperationException("订单已取消,无需退款");
  17. }
  18. }

完整状态流转示例

  1. var order = new OrderContext(new PendingState());
  2. order.ProcessPayment(); // 进入ProcessingState
  3. order.RequestRefund(); // 输出警告信息
  4. // 模拟支付成功回调
  5. order.TransitionTo(new PaidState());
  6. order.RequestRefund(); // 进入RefundingState

相关代码:https://github.com/huangmingji/design-pattern-learning/tree/main/design-pattern-learning-2

原文链接:https://www.cnblogs.com/huangmingji/p/18755997

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号