当前位置: 首页 > 后端技术 > Java

领域驱动设计实践:支付系统建模

时间:2023-04-01 15:26:46 Java

在Airwallex,领域驱动设计(DDD)方法用于指导如何对复杂的业务问题和系统设计进行建模。在此博客中,我们尝试全面介绍使用DDD模式对支付系统进行建模的实践。引言支付系统是一个相当复杂多变的系统,涉及范围很广,从订单、欺诈、通知、与各种支付方式的集成到资金清算和结算。大多数开发人员在处理一个复杂的系统时,可能会遇到一些边界和职责不明确的问题,一个大型应用程序有很多模型和业务逻辑。没有隔离和模块化:复杂的业务工作流和流程是混合的,难以扩展。没有关注点分离:核心业务逻辑与技术实现细节混合在一起。软件行业的许多设计模式都解决了这些问题,在Airwallex,我们试验了一种领域驱动设计(DDD)方法来对我们的支付系统进行建模,以管理系统设计中的复杂性。什么是DDD?领域驱动设计(DDD)是由埃里克·埃文斯(EricEvans)提出的。它是一组思想、原则和模式,有助于基于业务领域的底层模型设计软件系统。DDD有两个不同的空间:问题空间和解决方案空间。在问题空间中,您使用战略模式定义系统的大规模结构,重点是分析域、子域和通用语言。然而,在解决方案空间中,战术模式用于提供一组可用于创建域模型的设计模式。这些模式包括限界上下文、上下文映射、实体、聚合、域事件、域服务、应用程序服务和基础设施。这些战术模式将帮助您设计松散耦合和内聚的微服务。如何在实践中应用DDD想象一个场景,客户想以10美元的价格在商家的网站上购买一件T恤。客户可以使用多种支付方式支付T恤,例如Visa卡或微信钱包。客户付款后,商户可以从支付网关收到通知,然后他们可以向客户展示支付成功页面。商户可以在AirwallexWebapp中查看支付明细,这样他们就可以知道他为这件T恤获得了多少资金,Airwallex扣除了多少,以及资金何时会结算到他的Airwallex钱包。将按照以下步骤应用DDD对基于上述场景的支付系统进行建模。分析真实世界的业务用例以获取问题空间中的域和子域。通常,事件风暴是这个阶段的一个很好的工具。在解决方案空间中定义有界上下文在有界上下文中,应用战术DDD模式来定义实体、聚合、域服务、域事件等。使用上一步的结果来识别团队中的微服务。以下是分析结果。问题空间域支付系统子域——支付处理:商户可以通过各种支付方式接受客户的支付——**金融:商户支付资金的清算和结算。通用语言经过与领域专家的讨论,以下是所有团队接受的通用语言。-支付意向:商家创建的订单,指定价格、产品、客户等。-付款尝试:商家创建的交易,用于接受客户对特定订单的付款。-付款方式:客户为产品或服务付款的方式。-支付结算:一批支付结算到商户钱包。-付款视图:包含与付款相关的所有数据的汇总付款详细信息视图。解决方案空间限界上下文限界上下文(BC)定义领域模型的范围。从问题空间的分析结果,我们可以定义如下的限界上下文。-支付网关:API网关,为商家提供可靠的API来创建或查看支付。-支付核心:支付意图、尝试、方法资源管理。-支付适配器:与外部PSP(微信/支付宝/Visa/Mastercard等)集成。-付款结算:为商户计算并结算每笔付款的原则和费用。-支付融合:支付细节的聚合视图。而contextmap会是这样的:DomainModel从我们上面分析的场景和无处不在的语言,我们可以确定以下Aggregates,Entities,ValueObjects和DomainEvents。领域服务在我们的实践中,领域服务是聚合的无状态业务逻辑服务,遵循单一职责模式。通常,我们将领域仓库、聚合变更、领域事件发布封装在领域服务中。以PaymentAttemptExecutorService为例。领域事件领域事件可以使系统更具可扩展性并避免任何耦合——一个聚合不应该决定其他聚合应该做什么,以及时间耦合——支付的成功完成不依赖于所有进程同时可用。例如,当PaymentCaptureCommand将支付状态更改为已支付时,将发送域事件PaymentAttemptCapturedEvent以通知聚合的PaymentAttempt它已被捕获。在PaymentAttemptCapturedEvent的领域事件处理器中,我们可以在业务逻辑上添加副作用,比如通知支付融合边界上下文更新支付明细,通知支付结算边界上下文计算结算金额和手续费。基础设施在DDD模式中,基础设施层用于将核心业务领域与技术实现细节分开。通常,该层采用抗污染层(ACL)模式。以Realm仓库为例。域存储库只定义接口,例如它们可以做什么,但实现细节应该隐藏在基础架构层中,例如使用PostgreSQL或MongoDB存储数据。例如在基础设施层,PaymentAttemptPgRepository是基于PostgreSQL的具体实现,toPO是一个映射器,用于将领域对象PaymentAttempt转化为持久化对象。因此,在领域层,我们只关注领域模型,与基础设施技术完全解耦。当基础设施层有任何变化时,领域层不需要做任何改变。从领域模型到微服务我们现在已经为支付系统定义了一组限界上下文,并在每个限界上下文中确定了一组实体、聚合和领域事件服务。下一步是从领域模型到应用程序微服务的设计。在这里,我们选择将有界上下文映射到微服务。结论在这篇博客中,我们在尝试对支付系统建模时谈到了领域驱动设计(DDD)模式的各种概念和策略。采用DDD可以带来很多好处,例如所有团队之间的清晰沟通以及设计系统的成熟模式以管理复杂性并提供更好的可扩展性。使用无处不在的语言,我们可以实现更多的自描述类和函数名。通过聚合模式,我们可以实现清晰的边界和单一的责任。使用域事件模式,我们可以将核心业务流程与聚合的副作用分开。通过基础设施层和ACL模式,我们可以将核心业务领域模型从技术实现细节中分离出来。使用限界上下文模式,我们可以推断出潜在的微服务候选者。DDD模式是一个很大的话题,我认为我们还没有对它们进行充分的解释,但我们想涵盖一些关键话题和我们实践该模式的经验。未来,我们将继续深入研究DDD模式中的各个主题,例如层管理、领域事件存储、上下文映射模式等。