DDD 实践问题:如何实现基于数据库的实体属性有效性校验
推荐方案:领域服务收敛校验与创建逻辑
这是兼顾解耦、DRY原则和始终有效对象要求的最优解,具体实现逻辑如下:
- 在领域层定义抽象接口
IProductCategoryRepository,仅声明你需要用到的IsValid(string categoryName)方法,具体实现放在基础设施层,完全符合依赖倒置原则 - 领域层新增
ProductCategoryProvider领域服务,依赖IProductCategoryRepository抽象接口,将「字符串基础格式校验+数据库有效值校验+ProductCategory值对象创建」的全链路逻辑收敛到该服务内部实现 - 应用层所有需要创建
ProductCategory的场景,统一调用该领域服务的方法即可,无需重复实现校验逻辑,也不存在绕过校验的可能
原有两个方案的适用判断标准
如果不想引入领域服务,你可以根据以下两个维度直接选择原有方案:
选择方案1(应用层做校验)的前提
- 项目中
ProductCategory的使用场景不超过3处,且未来没有明显的新增使用场景的规划 - 业务规则允许存在临时未校验分类有效性的
ProductCategory实例,比如草稿态的产品不需要校验分类合法性,仅在正式提交时才需要校验
这种场景下方案1的实现复杂度最低,少量重复代码的成本远低于额外引入架构组件的成本。
选择方案2(值对象工厂调用仓储)的前提
- 业务规则要求所有
ProductCategory实例只要存在就必须是系统已登记的有效分类,不存在任何例外场景 - 你能接受领域层依赖抽象的仓储接口
这种场景下方案2的代码最简洁,约束性最强,不存在校验逻辑遗漏的可能。
关于领域层依赖仓储接口的合理性
这种做法完全符合DDD的设计原则。大家常说的「领域层不要依赖仓储」指的是不要依赖仓储的具体实现类,而不是不能依赖领域层自己定义的抽象仓储接口。依赖抽象接口不会让领域层耦合任何底层持久化技术,也不会破坏领域层的纯净性,是DDD推荐的标准做法。
内容的提问来源于stack exchange,提问作者M. Koch
相关产品推荐
相关产品推荐

