领域服务

DDD 学习笔记 | 极客时间 | 手把手教你落地 DDD

简介

使用 AI 评审图片服务的领域模型图,发现了「聚合根设计争议」推荐使用「领域服务」解决。修正后通过 AI 学习了「资源库模式 Repository Pattern」。

源码地址 aoemedia-server

聚合根设计争议

AI:当前将「图片搜索」作为聚合根值得商榷,搜索行为更适合作为领域服务

领域服务 Domain Service

按照面向对象的做法,领域逻辑本来最好放到领域对象中去,不过有些逻辑又不适合放到领域对象,这时,干脆放到一些只有方法没有状态的类里面。给这些类取个名字,就叫领域服务

极客时间原文:12|代码实现(下):怎样更加“面向对象”?

使用领域服务解决争议

AI:将「图片搜索」作为领域服务独立呈现,符合资源库模式的设计原则。

资源库模式 Repository Pattern

资源库模式(Repository Pattern)是领域驱动设计(DDD)中的一种核心模式,用于解耦领域模型与数据持久化逻辑,提供对领域对象的集合式操作接口。其核心目标是将领域层的业务逻辑与底层存储技术(如数据库、文件系统、外部API)隔离,使领域模型保持「持久化无关性」。

三个核心特征

  • 领域语义接口 资源库的接口设计基于业务需求,而非数据库操作(如FindByUserId而非Select * from table)。
  • 聚合根的门户 资源库的操作粒度是聚合根(而非单个实体或数据库表),确保事务一致性。
  • 基础设施解耦 具体实现属于基础设施层,可通过依赖注入替换存储方式(如MySQL、MongoDB、内存数据库)。

资源库 vs. DAO 模式

对比维度资源库(Repository)DAO(Data Access Object)
设计目标解耦领域模型与持久化逻辑,实现业务语义操作抽象数据库访问细节,提供通用数据操作接口
所属层级领域层(接口定义) + 基础设施层(实现)基础设施层(接口和实现均在此层)
操作对象聚合根(Aggregate Root)数据库表/ORM实体
方法命名反映业务意图(如findPendingOrders反映数据库操作(如insert, update
接口语义“像操作内存集合一样"管理领域对象生命周期“直接映射数据表"进行CRUD操作
事务边界以聚合根为事务一致性单元以单个数据库操作为原子单元
返回结果领域对象(如Order数据载体对象(如OrderEntity
技术耦合性接口无技术细节(如SQL),实现可替换存储方案通常与具体ORM框架(如Hibernate)或数据库强耦合
典型方法add(), remove(), findByCriteria()save(), delete(), selectByExample()
业务逻辑处理可能封装简单业务规则(如保存前的校验)仅处理数据访问,不涉及业务规则
测试友好性可通过内存实现快速测试领域逻辑通常需要Mock数据库连接进行测试
适用场景领域驱动设计(DDD)、复杂业务系统简单CRUD应用、快速数据原型开发
演化能力支持多存储方案切换(如DB->NoSQL)存储方案变更需重写DAO实现
与领域模型关系紧密绑定,理解领域上下文完全解耦,仅关注数据结构

核心区别图解

  +------------------+          +------------------+
  |   领域层          |          |   基础设施层     |
  |                  |          |                  |
  |  Repository接口  | <------ |  Repository实现  |
  |  (业务语义)       |          |  (DB/NoSQL实现)  |
  +------------------+          +------------------+
             ▲
             | 操作聚合根
             |
  +------------------+
  |   领域模型        |
  |   (聚合根)        |
  +------------------+

  +------------------+          +------------------+
  |   业务逻辑层      |          |   基础设施层     |
  |                  |          |                  |
  |   Service        | <------ |      DAO实现      |
  |                  |          |  (ORM/SQL实现)   |
  +------------------+          +------------------+
             ▲
             | 操作数据对象
             |
  +------------------+
  |   数据库表结构    |
  |   (Entity)       |
  +------------------+

何时选择?

模式典型场景
资源库1. 需要隔离领域逻辑与存储细节
2. 存在复杂聚合根操作
3. 预期未来更换存储技术
DAO1. 简单数据存取需求
2. 使用ORM框架快速开发
3. 不需要领域模型强一致性保障

混用风险警示

避免在同一个系统中同时暴露两种模式
(如:Service层同时调用Repository和DAO,会导致职责混乱)

comments powered by Disqus