一、前言常见的DDD实现架构有很多种,如经典四层架构、六边形(适配器端口)架构、整洁架构(Clean Architecture)、CQRS架构等。架构无优劣高下之分,只要熟练掌握就都是合适的架构。本文不会逐个去讲解这些架构,感兴趣的读者可以自行去了解。本文将带领大家从日常的三层架构出发,精炼推导出我们自己的应用架构,并且将这个应用架构实现为Maven Archetype,最后使用我们Archetype创建一个简单的CMS项目作为本文的落地案例。需要明确的是,本文只是给读者介绍了DDD应用架构,还有许多概念没有涉及,例如实体、值对象、聚合、领域事件等,如果读者对完整落地DDD感兴趣,可以到本文最后了解更多。二、应用架构演化我们很多项目是基于三层架构的,其结构如图:我们说三层架构,为什么还画了一层 Model 呢?因为 Model 只是简单的 Java Bean,里面只有数据库表对应的属性,有的应用会将其单独拎出来作为一个 Maven Module,但实际上可以合并到 DAO 层。接下来我们开始对这个三层架构进行抽象精炼。
2.1 第一步、数据模型与DAO层合并
为什么数据模型要与DAO层合并呢?首先,数据模型是贫血模型,数据模型中不包含业务逻辑,只作为装载模型属性的容器;其次,数据模型与数据库表结构的字段是一一对应的,数据模型最主要的应用场景就是DAO层用来进行 ORM,给 Service 层返回封装好的数据模型,供Service 获取模型属性以执行业务;最后,数据模型的 Class 或者属性字段上,通常带有 ORM 框架的一些注解,跟DAO层联系非常紧密,可以认为数据模型就是DAO层拿来查询或者持久化数据的,数据模型脱离了DAO层,意义不大。
2.2 第二步、Service层抽取业务逻辑
下面是一个常见的 Service 方法的伪代码,既有缓存、数据库的调用,也有实际的业务逻辑,整体过于臃肿,要进行单元测试更是无从下手。
这是典型的事务脚本的代码:先做参数校验,然后通过 biz1、biz2 等子方法做业务,并将其结果通过一堆 Set 方法设置到数据模型中,再将数据模型更新到数据库。由于所有的业务逻辑都在 Service 方法中,造成 Service 方法非常臃肿,Service 需要了解所有的业务规则,并且要清楚如何将基础设施串起来。同样的一条规则,例如if(condition1=true),很有可能在每个方法里面都出现。专业的事情就该让专业的人干,既然业务逻辑是跟具体的业务场景相关的,我们想办法把业务逻辑提取出来,形成一个模型,让这个模型的对象去执行具体的业务逻辑。这样Service方法就不用再关心里面的 if/else 业务规则,只需要通过业务模型执行业务逻辑,并提供基础设施完成用例即可。将业务逻辑抽象成模型,这样的模型就是领域模型。要操作领域模型,必须先获得领域模型,但此时我们先不管领域模型怎么得到,假设是通过loadDomain方法获得的。通过 Service方法的入参,我们调用loadDomain方法得到一个模型,我们让这个模型去做业务逻辑,最后执行的结果也都在模型里,我们再将模型回写数据库。当然,怎么写数据库的我们也先不管,假设是通过saveDomain方法。Service层的方法经过抽取之后,将得到如下的伪代码:
接下来我们要考虑在哪里实现DomainRepository。既然 DomainRepository 与底层数据库有关联,但是我们现在 DAO 层并没有引入 Domain 这个包,DAO 层自然无法提供 DomainRepository的实现,我们初步考虑是不是可以将 DomainRepository 实现在 Service 层。但是,如果我们在 Service 中实现DomainRepository,势必需要在 Service 层操作数据模型:查询出来数据模型再封装为领域模型、或者将领域模型转为数据模型再通过ORM 保存,这个过程不该是 Service 层关心的。因此,我们决定在 DAO 层直接引入 Domain 包,并在 DAO 层提供 DomainRepository 接口的实现,DAO 层查询出数据模型之后,封装成领域模型供DomainRepository 返回。这样调整之后, DAO 层不再向 Service 返回数据模型,而是返回领域模型,这就隐藏了数据库交互的细节,我们也把DAO层换个名字称之为Repository。现在,我们项目的架构图是这样的了:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验