DDD领域驱动设计系列-原理篇-战术设计

概述

上篇战略设计产出了领域及问题域领域模型;详见:DDD领域驱动设计系列-原理篇-战略设计-CSDN博客

战术设计篇聚焦如何落地,包含实际解决方案模型落地,架构分层(Clean,CQRS),Reposity模式落地实践(如何维护聚合);

战略设计输入

领域划分

划分4大域:结算用户域,计费,清算,结算;

问题域领域模型

战术设计-解决方案模型

解决方案模型可以从性能及实际落地因素来考虑;在结算中由于实际要通过接收交易确认收货消息来触发结算,出于保存结算时的原始数据快照便于后续有据可依这里抽出结算收单模型

这样最终的解决方案模型如下;

战术设计-架构分层

分层架构上是采用传统MVC还是DDD的六边型,Clean架构或者洋葱架构?

结论是:使用洋葱架构,原因:以领域实体为核心沉淀业务逻辑,外层依赖内层;架构上分为application service(业务流程编排),domain service(域服务),domain实体,以及入口服务&基础设施及外部业务依赖;

这样设计好处:1、基础设施变化不影响上层业务逻辑代码;2、更易理解维护及业务逻辑复用:业务逻辑沉淀在领域实体;

架构结果

各分层架构介绍

MVC

controller,service及dao层;缺点:1、所有的业务逻辑都写在service,复用度及可理解性不够;2、service直接依赖于Dao,当dao层实现有变化导致service变化;;

六边型

六边型核心思想是抽离业务入口为适配器入口适配器依赖于应用核心接口;同时应用核心依赖于基础设施及外部业务系统接口基础设施实现依赖于应用核心

这样好处较MVC架构来讲当基础设施实现变化不会影响应用核心,eg:消息由rabbitMq切换成rocketMq,上层应用核心代码不用变;

Clean架构

和六边型思路一致:分离基础设施&外部依赖;区别是明确定义了以领域实体为核心,外层是服务;

洋葱架构

更进一步定义了域服务及流程服务application service;基础逻辑与上述六边型&clean架构一致:基础设施&外部依赖可变化但不影响应用核心逻辑代码;

战术设计-CQRS

传统我们查询也会经过applicationService及domainService,但有时查询需要的内容不仅仅是领域模型此时就会导致领域模型耦合了和领域无关的内容;如订单列表展示需要商户额外的地点信息;

这里使用CQRS(Command Query Responsibility Segregation)架构模式;

查询方面直接由Api层查询reposity,减少中间层次转换&减少查询逻辑对于领域模型的入侵

战术设计-Reposity模式使用

为什么要用Reposity模式?

原因:1、解决传统service直接依赖Dao层导致Dao如果变化影响service代码大量改动;2、领域模型与持约化DO本身不是一对一等价关系,如合约领域模型实体Entity对应存储时涉及合约DO及合同条款DO;

Reposity分层架构

Domain Service层做为需求方负责制定需要的reposity存储接口,由Repsoity模块来进行实现;Reposity在实现的时候可对一个模型对象拆成多个DO存储或多个模型合成一个DO;

多个模型Entity对应一个DO场景:交易主单及子单是是多个模型,考虑到复用表结构,reposity在实现时会将主单与子单合统一转成一个交易表DO进行存储;

一个模型Entity对应多个DO场景:商品表考虑到性能会有商品主表及商品扩展表,在模型上商品是一个Entity,但在持久化时会拆成商品主表DO及商品扩展表DO进行持久化;

Reposity注意事项

标准的reposity接口有:save,query方法;其中save入参是领域模型Entity,如交易单存储入参是OrderModel,OrderModel包含了主单及子单;save方法通过聚合根entity是否有id来判断是插入还是更新;

但有时聚合根entity中有部分实体是没变化的,这个不需要进行更新,这个解决方案有变更追踪方案;

变更追踪原理:将入参的entity与数据库查询出来的entity进行比较(所有字段值)如果有变化才做更新;变更追踪方案有一定的复杂度(复杂度上来容易出问题),所以在实现时个人更倾向于由域服务决定要更新什么

比如交易支付场景对外提供交易支付接口,入参是:交易主单+交易子单;域服务这层针对入参子单进行处理(对子单调用支付域进行支付),最新调用reposity save时传入当前主单及当前支付的交易子单(而不是全部的交易子单)进行子单状态更新;

总结

本章介绍了DDD战术设计,描述了解决方案模型落地&分层架构选型&Reposity实现;

其中Reposity实现部分大的分层依赖是合理的,对于提升更新性能引入变更追踪导致的复杂度需要辩证去看

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
领域驱动设计(Domain-Driven Design,DDD)是一种软件开发方法,旨在将复杂的软件系统分解为多个领域,并将每个领域的业务逻辑提取出来进行分析和设计。除了DDD领域驱动设计,还有以下几种常见的软件设计方法: 1. 面向对象设计(Object-Oriented Design,OOD):面向对象设计是一种将系统分解为对象的软件设计方法,强调对象之间的关系和交互,倡导封装、继承和多态等概念。 2. 面向服务设计(Service-Oriented Design,SOD):面向服务设计是一种将系统分解为服务的软件设计方法,强调服务之间的松耦合和可重用性,倡导将系统功能模块化,以服务为中心构建系统。 3. 面向接口设计(Interface-Oriented Design,IOD):面向接口设计是一种将系统分解为接口的软件设计方法,强调定义清晰的接口和规范的通信协议,以便不同模块之间可以相互协作和交互。 4. 领域特定语言设计(Domain-Specific Language Design,DSL):领域特定语言设计是一种通过定义特定领域的语言和规则来描述系统的软件设计方法,强调使用领域专用的语言和工具来描述系统的业务逻辑和规则。 除了上述常见的软件设计方法外,还有许多其他方法和技术,如面向数据设计、面向测试设计、面向切面设计等,可以根据具体的项目需求和情况选用不同的设计方法来进行软件系统的开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值