在开发电商支付模块时,我们常遇到这样的状态流转需求:
待支付
支付中
支付成功/失败
退款处理
传统的 if-else 或 switch 实现方式会导致:
if-else
switch
此时,状态模式(State Pattern)是这些问题的最佳解决方案。
通过将状态抽象为独立类,实现两大关键特性:
// 订单状态抽象接口public interface IOrderState{ void Process(OrderContext context); void Cancel(OrderContext context); void Refund(OrderContext context);}// 订单上下文(维护当前状态)public class OrderContext{ private IOrderState _currentState; public string OrderId { get; } = Guid.NewGuid().ToString(); public OrderContext(IOrderState initialState) { TransitionTo(initialState); } public void TransitionTo(IOrderState state) { Console.WriteLine($"订单状态变更:{_currentState?.GetType().Name} → {state.GetType().Name}"); _currentState = state; } public void ProcessPayment() => _currentState.Process(this); public void CancelOrder() => _currentState.Cancel(this); public void RequestRefund() => _currentState.Refund(this);}
// 订单状态抽象接口
public interface IOrderState
{
void Process(OrderContext context);
void Cancel(OrderContext context);
void Refund(OrderContext context);
}
// 订单上下文(维护当前状态)
public class OrderContext
private IOrderState _currentState;
public string OrderId { get; } = Guid.NewGuid().ToString();
public OrderContext(IOrderState initialState)
TransitionTo(initialState);
public void TransitionTo(IOrderState state)
Console.WriteLine($"订单状态变更:{_currentState?.GetType().Name} → {state.GetType().Name}");
_currentState = state;
public void ProcessPayment() => _currentState.Process(this);
public void CancelOrder() => _currentState.Cancel(this);
public void RequestRefund() => _currentState.Refund(this);
public class PendingState : IOrderState{ public void Process(OrderContext context) { Console.WriteLine("开始支付处理..."); // 调用支付网关接口 context.TransitionTo(new ProcessingState()); } public void Cancel(OrderContext context) { Console.WriteLine("订单已取消"); context.TransitionTo(new CanceledState()); } public void Refund(OrderContext context) { Console.WriteLine("待支付订单不能退款"); throw new InvalidOperationException("待支付订单不能退款"); }}
public class PendingState : IOrderState
public void Process(OrderContext context)
Console.WriteLine("开始支付处理...");
// 调用支付网关接口
context.TransitionTo(new ProcessingState());
public void Cancel(OrderContext context)
Console.WriteLine("订单已取消");
context.TransitionTo(new CanceledState());
public void Refund(OrderContext context)
Console.WriteLine("待支付订单不能退款");
throw new InvalidOperationException("待支付订单不能退款");
支付中状态:
public class ProcessingState : IOrderState{ public void Process(OrderContext context) { Console.WriteLine("支付处理中..."); context.TransitionTo(new PaidState()); } public void Cancel(OrderContext context) { Console.WriteLine("支付处理中,不可取消订单..."); throw new InvalidOperationException("支付处理中,不可取消订单..."); } public void Refund(OrderContext context) { Console.WriteLine("支付未完成不能退款"); throw new InvalidOperationException("支付未完成不能退款"); }}
public class ProcessingState : IOrderState
Console.WriteLine("支付处理中...");
context.TransitionTo(new PaidState());
Console.WriteLine("支付处理中,不可取消订单...");
throw new InvalidOperationException("支付处理中,不可取消订单...");
Console.WriteLine("支付未完成不能退款");
throw new InvalidOperationException("支付未完成不能退款");
支付成功状态:
public class PaidState : IOrderState{ public void Process(OrderContext context) { Console.WriteLine("订单已完成支付"); throw new InvalidOperationException("订单已完成支付"); } public void Cancel(OrderContext context) { Console.WriteLine("已支付订单需走退款流程"); throw new InvalidOperationException("已支付订单需走退款流程"); } public void Refund(OrderContext context) { Console.WriteLine("发起退款申请..."); // 调用退款接口 context.TransitionTo(new RefundingState()); }}
public class PaidState : IOrderState
Console.WriteLine("订单已完成支付");
throw new InvalidOperationException("订单已完成支付");
Console.WriteLine("已支付订单需走退款流程");
throw new InvalidOperationException("已支付订单需走退款流程");
Console.WriteLine("发起退款申请...");
// 调用退款接口
context.TransitionTo(new RefundingState());
退款中状态:
public class RefundingState : IOrderState{ public void Process(OrderContext context) { Console.WriteLine("退款处理中..."); context.TransitionTo(new RefundedState()); } public void Cancel(OrderContext context) { Console.WriteLine("退款处理中,不可取消订单..."); throw new InvalidOperationException("退款处理中,不可取消订单..."); } public void Refund(OrderContext context) { Console.WriteLine("退款处理中,不可重复退款"); throw new InvalidOperationException("退款处理中,不可重复退款"); }}
public class RefundingState : IOrderState
Console.WriteLine("退款处理中...");
context.TransitionTo(new RefundedState());
Console.WriteLine("退款处理中,不可取消订单...");
throw new InvalidOperationException("退款处理中,不可取消订单...");
Console.WriteLine("退款处理中,不可重复退款");
throw new InvalidOperationException("退款处理中,不可重复退款");
退款完成状态:
public class RefundedState : IOrderState{ public void Process(OrderContext context) { Console.WriteLine("退款完成,订单已取消"); throw new InvalidOperationException("退款完成,订单已取消"); } public void Cancel(OrderContext context) { Console.WriteLine("订单已退款,无需取消"); throw new InvalidOperationException("订单已退款,无需取消"); } public void Refund(OrderContext context) { Console.WriteLine("订单已退款,无需退款"); throw new InvalidOperationException("订单已退款,无需退款"); }}
public class RefundedState : IOrderState
Console.WriteLine("退款完成,订单已取消");
throw new InvalidOperationException("退款完成,订单已取消");
Console.WriteLine("订单已退款,无需取消");
throw new InvalidOperationException("订单已退款,无需取消");
Console.WriteLine("订单已退款,无需退款");
throw new InvalidOperationException("订单已退款,无需退款");
订单取消状态:
public class CanceledState : IOrderState{ public void Process(OrderContext context) { Console.WriteLine("订单已取消,无需支付"); throw new InvalidOperationException("订单已取消,无需支付"); } public void Cancel(OrderContext context) { Console.WriteLine("订单已取消,无需取消"); throw new InvalidOperationException("订单已取消,无需取消"); } public void Refund(OrderContext context) { Console.WriteLine("订单已取消,无需退款"); throw new InvalidOperationException("订单已取消,无需退款"); }}
public class CanceledState : IOrderState
Console.WriteLine("订单已取消,无需支付");
throw new InvalidOperationException("订单已取消,无需支付");
Console.WriteLine("订单已取消,无需取消");
throw new InvalidOperationException("订单已取消,无需取消");
Console.WriteLine("订单已取消,无需退款");
throw new InvalidOperationException("订单已取消,无需退款");
var order = new OrderContext(new PendingState());order.ProcessPayment(); // 进入ProcessingStateorder.RequestRefund(); // 输出警告信息// 模拟支付成功回调order.TransitionTo(new PaidState());order.RequestRefund(); // 进入RefundingState
var order = new OrderContext(new PendingState());
order.ProcessPayment(); // 进入ProcessingState
order.RequestRefund(); // 输出警告信息
// 模拟支付成功回调
order.TransitionTo(new PaidState());
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