简介
使用 AI 评审图片服务的领域模型图,发现了「聚合根设计争议」推荐使用「领域服务」解决。修正后通过 AI 学习了「资源库模式 Repository Pattern」。
源码地址 aoemedia-server
聚合根设计争议
AI:当前将「图片搜索」作为聚合根值得商榷,搜索行为更适合作为领域服务
领域服务 Domain Service
按照面向对象的做法,领域逻辑本来最好放到领域对象中去,不过有些逻辑又不适合放到领域对象,这时,干脆放到一些只有方法,没有状态的类里面。给这些类取个名字,就叫领域服务。
使用领域服务解决争议
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. 预期未来更换存储技术 |
DAO | 1. 简单数据存取需求 2. 使用ORM框架快速开发 3. 不需要领域模型强一致性保障 |
混用风险警示
❌ 避免在同一个系统中同时暴露两种模式
(如:Service层同时调用Repository和DAO,会导致职责混乱)