论软件设计模式及其应用
三、正文
摘要
2023年 3 月,我所在的公司承接了某油企智慧加油站平台的建设工作。该项目旨在帮助加油站提升运营效率、降低运营成本和提高销售额。我在该项目中担任系统架构设计师,负责整个系统的架构设计工作。本文以该项目为例,详细论述了软件设计模式在支付场景中的具体应用。在支付场景中,我们用到的设计模式主要包括策略模式、模板方法模式和代理模式。我们运用策略模式实现了对多种支付方式的支持和灵活替换,提升了顾客支付的便利性;运用模板方法模式实现了支付处理流程的标准化,降低了支付出错的风险;运用代理模式实现了第三方支付平台的流量治理,提高了系统的可用性。整个项目历时 10 个月开发完成,并于 2023年 12 月正式交付并稳定运行至今,各项功能和性能指标均达到了客户要求,得到了客户和各级领导的一致好评。
正文
随着国内成品油零售行业竞争日益激烈,某油企为增强市场竞争力,决定建设一个智慧加油站平台,通过引入信息技术来优化运营管理,进一步提升加油站的管理水平和服务质量。我所在的单位成功中标该项目,并于 2023年 3 月正式启动该项目的建设工作。我被任命为系统架构设计师,负责该项目的系统架构设计工作。
该项目的主要建设内容包括智慧支付、智慧营销、智慧运营等功能模块。其中智慧支付模块提供了对多种支付方式的支持,比如现金支付、油卡支付、微信支付、支付宝支付、云闪付支付、车牌付、人脸付、ETC 支付等,以确保顾客下单支付的便利性和安全性;智慧营销模块支持开展多种形式的营销活动,比如消费返券、趣味抽奖、积分任务、限时秒杀、充值优惠等,以提高顾客复购率;智慧运营模块涵盖了站务管理、运营数据统计分析等功能,以提高加油站运营效率。该项目选用 Java 做为主要开发语言,运用基于 Spring Cloud Alibaba 的微服务架构进行构建。我们选择 MySQL 作为数据库,Doris 作为实时数仓,Redis 作为分布式缓存,RocketMQ 作为消息中间件,Flink 作为实时流式计算引擎,并最终在 Kubernetes 集群中部署运行。要想高质量地完成该项目,运用合适的设计模式显得至关重要。
常见的设计模式主要有以下几类:创建型设计模式、结构型模式和行为型模式。其中,创建型模式对类的实例化过程进行了抽象,能够使软件模块做到与对象的创建和组织无关。创建型模式主要关注对象的创建过程,将对象的创建和使用分离,以提高系统的灵活性和扩展性。常见的创建型模式有单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式等。结构型模式主要关注对象和类的组织结构,通过组合和继承等方式实现更复杂的功能,常见的结构型模式有适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。行为型设计模式主要关注对象之间的交互和通信,以实现更复杂的行为,常见的行为型模式有责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、策略模式、模板方法模式和访问者模式等。
在该系统中,智慧支付模块是最核心的模块之一,且对扩展性和安全性有较高的要求。扩展性方面,该模块需要支持多种支付方式,且需要根据市场的变化方便地增加新的支付方式。安全性方面,如果该模块出错, 将会给加油站带来严重的资金损失或法律风险。为了改善智慧支付模块的扩展性和安全性,我们运用了策略模式、模板方法模式和代理模式。下面将详细阐述这三种设计模式在智慧支付模块中的具体应用。
一、策略模式
我们运用策略模式实现了对多种支付方式的支持和灵活替换,提升了顾客支付的便利性。策略模式是指将一组算法封装起来,让它们可以互相替代,从而使算法的变化独立与使用算法的客户端。
为了支持多种支付方式,我们面临的主要挑战是:每种支付方式需要与不同的支付平台对接,虽然最终实现的功能相同,但每个平台的接口协议、签名算法与加密算法有所差异。如果将所有支付方式的处理逻辑放在同一个方法中,这个方法会变得过于复杂,难以阅读和维护。一旦需要新增支付方式或调整现有方式,我们就必须在庞大的代码中查找和修改相关部分,这容易引入错误,并且每次改动后都需要重新全面测试支付流程,以防止破坏其他支付方式的正常运行。
为解决这个问题,我们运用了策略模式。首先,我们对支付方式建立了一个一致性的抽象,即设计了支付策略接口 PayStrategy
,并定义了创建支付单、查询支付单状态、取消支付、退款等方法,用于屏蔽不同支付平台之间的接口差异,让调用方不必关心具体的技术实现细节。然后,我们分别为每个第三方支付平台创建了对应的支付策略实现类,用于封装各自平台特有的处理逻辑。最后,我们设计了一个支付策略工厂,用于在运行时动态地根据用户选择的支付方式获取对应的支付策略的实例对象,而无需关注具体是哪一个实现类。这样一来,当用户选择支付方式并发起支付时,系统就能从支付策略工厂中得到对应的支付策略对象,进而调用该对象中的 创建支付单
方法来发起支付。当需要新增新的支付方式时,只需要新增对应的支付策略实现类即可,无需修改调用方的代码。
通过策略模式的运用,我们有效地解决了支付方式多样化带来的挑战,同时增强了系统的可维护性和可扩展性。
二、模板方法模式
我们运用模板方法模式实现了支付处理流程的标准化,降低了支付出错的风险。模板方法模式是指允许在父类中定义一个算法的骨架,而将某些步骤延迟到子类中实现。
在运用策略模式实现了对多种支付方式的支持和灵活替换后,我们又面临了新的挑战,即无论是哪一种支付方式,当用户发起支付时,系统都需要按照以下步骤处理:检查本地订单支付状态、创建支付单、查询支付单状态、支付金额检查、更新本地订单支付状态,任何一个环节失误,都可能造成严重的后果,比如在创建支付单之前未检查订单状态可能会导致重复支付,或者在更新本地订单状态之前未检查应付金额和实付金额是否一致可能会导致法律纠纷或资金损失。如果分别在不同的支付策略实现类中实现这些逻辑,极有可能由于开发人员的疏忽而遗漏某些关键环节。
为了避免这种情况,我们运用了模板方法模式。我们设计了一个抽象类 AbstractPayStrategy
,该类扩展了 PayStrategy
接口,并将 PayStrategy
中的 创建支付单
方法作为模板方法,在模板方法中实现了支付处理流程的标准化编排。同时定义了各个处理步骤对应的方法。其中,检查本地订单支付状态、更新本地订单支付状态等与具体支付平台无关的方法定义为实例方法;创建支付单、查询支付单状态与具体支付平台相关的方法定义为抽象方法,延迟到支付策略子类中实现。支付策略子类通过继承 AbstractPayStrategy
并实现抽象方法,即可实现支付处理流程的标准化。由于子类中必须实现抽象方法,否则代码无法编译通过,这就消除了开发人员遗漏某些关键步骤的可能,从而降低了支付出错的风险。
通过模板方法模式的运用,我们确保了支付处理流程的标准化,有效降低了支付出错的风险。
三、代理模式
我们运用代理模式实现了第三方支付平台的流量治理,提高了系统的稳定性。代理模式是指通过一个代理对象控制对目标对象的访问。
在系统试运行过程中,我们发现第三方支付平台偶尔会出现服务不稳定或响应缓慢的情况,这可能会影响到我们整个支付流程的性能和用户体验。
为了解决这个问题,我们采用了代理模式来实现对第三方支付平台的流量治理,从而提高了系统的稳定性和响应速度。我们设计了一个名为 PayStrategyProxy
的代理类,该类同样实现了 PayStrategy
接口,这意味着它可以作为任何支付策略实现类的代理。 PayStrategyProxy
内部持有一个指向实际支付策略实现类的引用,这允许代理在必要时调用实际对象的方法,同时在调用前后执行额外的逻辑处理。在该代理类中,我们主要实现了负载均衡、限流、熔断、监控告警等流量治理措施,比如当检测到第三方支付平台的响应时间显著增加或失败率超过预设阈值时,代理将自动停止转发请求,直至服务恢复正常。
通过代理模式的运用,有效提升系统的整体稳定性和安全性,为用户提供更加顺畅、安全的支付体验。
通过上述设计模式的运用,智慧支付模块的扩展性和安全性得到了提升。最终,经过 10 个月的研发,该项目于 2023年 12 月完成并交付上线,至今运行稳定,各项功能和性能指标均达到客户要求,得到了客户和各级领导的一致好评。虽然项目取得了成功,但我们也看到了一些不足之处,其中需求频繁变更导致项目团队经常加班是比较突出的问题。针对这个问题,我们采取了以下两个措施:一是规范需求变更流程,提升变更成本,以避免过度的需求变更;二是通过灵活的配置和架构设计,低成本响应需求变更。
通过该项目的开发,我在系统分析与设计方面积累了不少宝贵的经验,为我后续的工作提供了很大的帮助。这也激励着我不断学习,不断丰富自己的知识体系,为将来能够应对更复杂的工作做好准备。论软件设计模式及其应用