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

news/2025/3/6 17:50:11/文章来源:https://www.cnblogs.com/huangmingji/p/18755997

支付场景中的状态流转

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

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

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

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

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

状态模式核心思想

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

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

状态模式实现

  1. 状态接口设计
// 订单状态抽象接口
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);
}
  1. 具体状态类实现
    待支付状态:
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 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 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 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 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("订单已取消,无需退款");}
}

完整状态流转示例

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/894721.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Webshell不出网】reGeorg和Pystinger的使用

reGeorg+Proxifier: 在实战情况下有时会遇到外网Getshell准备内网渗透的时候发现目标机器不出网,所以就会用映射,代理..等等方式进行上线。 reGeorg项目地址为: https://gitcode.net/mirrors/sensepost/reGeorg?utm_source=csdn_github_acceleratorProxifier地址: https:…

【测试】钩子测试

图片钩子测试 仅收集了访问数据,未使用任何js信息,未窃取任何cookie 只用于匿名数据收集,以及,好玩。

什么!GIS地形与数字孪生结合,竟然能做出如此有趣的效果!

山海鲸可视化支持添加ArcGIS和Cesium地形,并且添加后的GIS地形能够完美与整个数字孪生系统进行融合。同时,我们也可以对GIS地形进行编辑,通过鼠标点击圈选编辑区域,可以将区域内的地形压平、抬升或下沉,结合数字孪生能够实现许多有趣的效果。下面我们就来看看,如何在山海…

中国PostgreSQL考试认证体系

中国PostgreSQL考试认证体系 一、关于举办PostgreSQL研修与评测的通知 为深入贯彻党的二十大和全国新型工业化推进大会精神,落实《关于加强和改进工业和信息化人才队伍建设的实施意见》等文件精神,由北京神脑资讯技术有限公司主办的PostgreSQL数据库管理人才研修与评测班将于…

模型上新!来通义灵码体验 QwQ-32B 推理模型!

通义灵码目前已经支持 QwQ-plus 模型,欢迎大家在【智能问答】里,选择切换模型,即可体验更小尺寸、更强性能的新模型!今天,阿里云发布并开源全新的推理模型通义千问QwQ-32B。通过大规模强化学习,千问QwQ-32B在数学、代码及通用能力上实现质的飞跃,整体性能比肩DeepSeek-R…

python install spacy 报错解决

python install spacy 法1 修改setuptool版本(无效)法2 安装前置依赖(无效)pip install numpy cython jinja2 pathlib preshed thinc cymem murmurhash blis plac 法3 使用预编译的轮子文件安装(有效)pip install --prefer-binary spacy

可视化大屏出圈密码: 地图组件深度解析

01 组件介绍 在数据可视化大屏搭建中,地图组件是使用最频繁且重要的组件之一。它不但能直观展现地理方位相关信息,还能通过与标记点、飞线、图表等各类组件巧妙搭配,达成更加多元、生动的数据呈现效果,在众多行业领域都得到了广泛应用。鉴于其强大的适配能力,面对包含地理…

.NET 9.0 全栈技术的高效开源低代码平台(Vue3+Element-Plus)

前言 推荐一款基于.NET 9.0 全栈框架的新一代技术架构(Vue3+Element-Plus),开源低代码平台-Microi吾码。 平台不仅无限制地支持用户数、表单数、数据量及数据库数量,还通过跨平台兼容性实现了对多种开发语言的支持,并确保了在不同数据库间的无缝操作。 它还具备分布式部署…

Hula项目部署(桌面即时通讯应用程序)

后端项目部署: HuLaSpark/HuLa-Server: ☕️ HuLa 服务端,基于SpringBoot3 + Netty + MP + RocketMQ docker-compose.yml没有修改,有需要的话自行调整即可,我这里只是为了演示。 以下的命令在linux下运行,且windows可以直接访问 docker-compose up -d 直接拉取镜像启动存储…

linux核心命令

1、查询帮助命令 man ls help info2、文件和目录操作命令 ls # 仅了列出当前目录可见文件 ls -l # 列出当前目录可见文件详细信息 ls -hl # 列出相信信息并以可读大小显示文件大小 ls -al # 列出所有文件(包含隐藏)的详细信息 ls --human-r…

软工作业2-个人项目

项目地址 YiLaiL的个人项目 PSP表格PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)Planning 计划 10 30 Estimate估计这个任务需要多少时间 10 30Development 开发 455 640 Analysis需求分析 (包括学习新技术) 30 120 Design Spec生成设计文…

Easyexcel(3-文件导出)

EasyExcel 是一个便捷、高效的Excel读写库,尤其在大数据量的文件导出场景中表现出色。其核心优势在于减少内存占用和提升数据处理速度,适合用于Java项目中大批量数据的导出。响应头设置 通过设置文件导出的响应头,可以自定义文件导出的名字信息等 //编码格式为UTF-8 respons…