导语

在当今微服务架构与领域驱动设计(DDD)日益普及的背景下,一个长久困扰着技术团队的“老问题”再度引发行业热议:当我们在DDD的聚合根中精心维护业务不变量(Invariants)时,为何总是在传入DTO层又不得不重复编写相似的验证逻辑? 这种“同一件事做两遍”的困境,不仅导致代码冗余、维护成本飙升,更模糊了领域层的边界,让DDD的核心价值大打折扣。为此,本报记者深入多家技术团队,专访多位架构专家,试图揭开这一现象背后的根源与解法。

一、现象:验证代码的“双轨制”蔓延

在一家头部互联网金融企业的技术复盘会上,高级架构师李明(化名)展示了一组令人忧心的数据:其核心交易系统的用户信息修改模块(ChangeUserInfoCommand)中,DTO层与领域层分别实现了“年龄不能为负”“手机号格式核验”“用户名长度限制”等12项相同规则的验证,代码重合度超过70%。“每次业务规则变动,两个地方都要改,漏一个就是线上事故。”李明无奈地说。

这并非孤例。在电商、医疗、政务等多个领域的DDD实践者中,类似场景比比皆是。记者调查发现,绝大多数团队在构建系统时,遵循了“管道+过滤器”的经典模式:外部请求首先抵达DTO层(通常承载于Controller或API Gateway内),进行基础格式校验(如非空、长度、枚举范围等);随后请求进入应用服务层,触发领域层的业务逻辑,而领域层内部再次对数据完整性、一致性进行二次校验。这本是出于“防御性编程”的考虑,却意外造就了“验证双轨制”。

二、根源:不变量与DTO的不同“立场”

要理解重复验证为何产生,需先厘清DDD中“不变量”的本质。根据DDD奠基人Eric Evans的定义,不变量(Invariant)是聚合根在生命周期的任何时刻都必须满足的业务规则,例如“订单总额必须等于所有订单项金额之和”。这些规则内嵌于领域模型本身,是业务语义的直接体现,决不允许被绕过。

然而,传入DTO(Data Transfer Object)作为系统边界的“守门人”,其验证逻辑往往聚焦于数据格式与传输完整性,比如“用户名不能为空”“年龄必须是正整数”。这些规则属于技术层面的防御,并非核心业务的不变量。当两者恰好“同名不同义”时(如“年龄不能为负”既是技术校验也是业务约束),开发者便习惯性地在两个地方写同样的代码。

更深层的原因在于:DTO验证的典型实现(如JSR-303注解或FluentValidation)与领域模型的调用时机存在鸿沟。 领域层希望在聚合根被构造时即确保不变量,而DTO层则在反序列化阶段就已检查过。若两者未明确分工,就会陷入“你验一遍,我再验一遍”的怪圈。

三、专家观点:三种主流解决思路

针对这一顽疾,记者采访了多位技术专家,归纳出三种主流治理方案。

方案一:DTO验证仅做“枯萎校验”,领域不变量负责“完整约束”

某互联网大厂技术VP张伟指出:“DTO层只承担‘防呆’功能——禁止空指针、格式错误等明显非法的数据传入;而业务相关的复杂规则(如‘转账金额不得大于账户余额’)则完全交给领域层。”这一方式要求团队在代码评审中明确区分“什么是技术合规,什么是业务合规”,并通过命名规范(如DTO字段使用“IsValidFormat”方法,领域层使用“CheckInvariant”)强化边界。

方案二:统一验证入口,强制在聚合根构造函数中完成

知名DDD社区贡献者刘枫提出了更激进的方案:废除DTO层的业务相关注解,所有数据完整性与业务一致性验证全部强制放入聚合根的工厂方法或构造器中。 例如,当创建User聚合时,构造函数内自动校验年龄、手机号等规则,失败则抛出领域异常。而DTO层仅保留字段映射与JSON解析功能。“这样即使有人通过后台接口直接构造聚合,也逃不过不变量检查。”刘枫强调。

方案三:引入验证抽象层,实现“一次编写,两端复用”

另一种实用主义方案是提取公用的验证规范定义。例如,将“用户年龄规则”封装成独立的规范类(Specification),DTO层与领域层都引用同一份元数据。这样修改规则只需改动一处,并能通过自动化测试保证同步。目前已有Spring Validation的自定义注解与领域规范库相结合的成熟案例。

四、行业反思:莫让重复验证消解DDD价值

在采访的尾声,多位专家不约而同地表达了对DDD实践异化的担忧。“很多人把DDD当成‘分层代码生成器’,用了聚合、仓库、领域事件,却忘了核心是不变量和封装。”一位曾在知名国际咨询机构担任首席顾问的业内人士坦言,“当团队把精力耗费在填补DTO与领域层的验证缝隙上时,已经偏离了DDD的初衷——让领域逻辑成为系统的唯一真相源。”

或许,解决重复验证问题的关键,不在于找到“完美的技术方案”,而在于建立清晰的认知:领域不变量是系统的宪法,DTO验证只是执勤的门卫。 门卫可以筛选身份证,但无权修改宪法条款。当团队真正理解这一层抽象,重复验证的沉疴才有望根治。


(本报记者 陈越 报道)