找回密码
 立即注册
首页 业界区 业界 设计模式学习:状态模式实现订单状态流转 ...

设计模式学习:状态模式实现订单状态流转

志灿隐 2025-6-1 23:35:53
支付场景中的状态流转

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

  • 订单需要经历 待支付 → 支付中 → 支付成功/失败 → 退款处理 的完整生命周期。
  • 不同状态下可执行的操作不同(例如只有支付成功才能退款)。
  • 状态转换需要触发附加操作(支付成功要发通知、更新库存)。
传统的 if-else 或 switch 实现方式会导致:

  • 代码臃肿,维护困难
  • 状态转换逻辑分散
  • 新增状态需要修改大量现有代码
此时,状态模式(State Pattern)是这些问题的最佳解决方案。
状态模式核心思想

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

  • 行为状态化 :不同状态下相同的操作产生不同结果
  • 转换自动化 :状态对象自行决定下一个状态
状态模式实现


  • 状态接口设计
  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.    
  14.     public OrderContext(IOrderState initialState)
  15.     {
  16.         TransitionTo(initialState);
  17.     }
  18.     public void TransitionTo(IOrderState state)
  19.     {
  20.         Console.WriteLine($"订单状态变更:{_currentState?.GetType().Name} → {state.GetType().Name}");
  21.         _currentState = state;
  22.     }
  23.     public void ProcessPayment() => _currentState.Process(this);
  24.     public void CancelOrder() => _currentState.Cancel(this);
  25.     public void RequestRefund() => _currentState.Refund(this);
  26. }
复制代码

  • 具体状态类实现
    待支付状态:
  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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

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