领域驱动设计指南:事实与谬误之DDD 与 MVC
参考
本文有以下几个目的
- 让新手少交智商税,少浪费时间看一些软文。
- 普及一个基本概念:了解一项观点的提出年代和最初初衷,才能更好地掌握其精粹。
- 我想指出市场上一些误人子弟的软文。
首先说明:文中所说的谬误并非原书的谬误,而是很多网上水军写的软文在不断误人子弟、传播错误认知。
MVC到底在说什么
MVC(Model-View-Controller)架构由挪威计算机科学家Trygve Mikkjel Heyerdahl Reenskaug于1979年在施乐帕克研究中心(Xerox PARC)访问期间提出。这一架构最初是为Smalltalk编程语言设计的,旨在解决图形用户界面(GUI)开发中数据管理与用户交互的复杂性问题。当时Smalltalk的GUI需要支持动态交互(如用户操作实时更新数据),传统单体架构难以维护,MVC通过解耦输入-处理-输出流程,首次实现了界面与逻辑的分离。
Reenskaug认为,GUI应用需要将不同功能模块解耦,以应对数据复杂性和用户交互的动态性。他提出将软件系统划分为三个核心组件:
- 模型(Model) :封装数据和业务逻辑,独立于界面展示,例如数据库结构或业务规则。
- 视图(View):负责用户界面的呈现,直接与用户交互,例如窗口、按钮等可视化元素。
- 控制器(Controller):协调模型与视图的交互,处理用户输入并更新模型状态,例如按钮点击后的逻辑判断。
MVC的Model本身包含基础业务逻辑(如数据验证),但复杂业务场景下需独立的应用逻辑层(如Service层)来组织流程,这与DDD的领域建模形成互补。因此,四层架构(Model-View-Controller-Service)的出现是企业级开发的演进,而非MVC原生缺陷。
DDD到底在说什么
DDD由Eric Evans 在2003年出版的经典著作《领域驱动设计:软件核心复杂性应对之道》中系统提出。其诞生源于对复杂业务系统开发困境的反思:
-
传统开发的痛点:
- 软件模型与真实业务领域脱节,导致需求频繁变更时难以维护;
- 技术团队与领域专家(如业务分析师、行业专家)沟通低效,术语不统一,模型设计偏离实际业务逻辑;
- 当业务复杂度高(如金融、供应链、医疗等领域)时,传统开发方法(如数据驱动设计、贫血模型)无法有效管理复杂性,代码逐渐沦为"意大利面条"。
-
核心目标 :
Evans认为,应对复杂业务系统的关键在于将领域知识作为设计的核心,通过建立清晰、准确的领域模型,让技术实现紧密贴合业务本质,从而提升系统的可维护性和扩展性。
-
- 战略设计:通过限界上下文(Bounded Context)划分业务边界,明确领域模型的适用范围(如电商中的"订单域"与"支付域"),解决业务与技术对齐问题;
- 战术设计:通过实体、值对象、聚合根等工具实现领域模型,确保业务规则封装在代码中。
DDD与MVC并不冲突
在传统MVC架构下,解决GUI问题时,我们会设计GUI层面的技术模型,再根据模型渲染界面。同理,解决业务逻辑问题时,也可以设计一个领域模型,再基于模型开发业务逻辑。

从图中不难看出:领域驱动设计的核心是教你如何设计业务逻辑, 注意,是"业务逻辑设计",而非技术分层设计。原因很简单:DDD原书明确指出,这不是一本教你写代码的书,而是教你如何应对复杂软件的方法论。
无论哪个层面的技术开发,都可以先建模,再基于模型开发, 这是几乎所有行业都在使用的通用手段。
DDD本来就不存在统一的代码规范,原书也未给出具体实现手段
回到上图,你会发现:任何一个技术维度的修改,都不需要其他维度的直接支持,甚至可以单独调整某个维度------这正是DDD在战术设计上想表达的理念。但这部分内容被放在原书的最后章节,不仅因为前面的章节是前提,更因为代码架构并非DDD的核心。
DDD的核心是什么?
- 统一语言:团队(包括业务专家)使用一致的术语描述业务规则(如"订单已支付"对应领域事件);
- 领域模型:围绕业务概念设计代码,而非围绕数据库或技术框架;
- 解耦思想:通过聚合根、仓储等模式隔离业务逻辑与技术细节。
DDD 的本质是什么?
DDD 本质上是一种思想哲学与行为准则,而非可直接套用的代码模板。它要求开发者从 “技术驱动” 转向 “业务驱动”,就像面向对象设计中的 “接口定义契约”——DDD 定义了 “如何将业务知识转化为有效模型” 的抽象原则(如建立统一语言、识别领域边界、封装业务规则),但具体的实现路径需要团队结合业务特性与技术栈自主设计。例如,统一语言的落地需要团队共同梳理领域术语表,领域模型的构建需要分析业务实体间的依赖关系,这些都不是 “照搬代码模板” 就能完成的,而是需要通过持续的领域分析、团队协作和架构演进才能实现。这种思想上的转变,如同在编程中从 “关注具体实现” 到 “关注抽象契约” 的升华 ——DDD 提供的是 “做什么” 的方向,而非 “怎么做” 的标准答案,最终的架构形态需要开发者像实现接口一样,用代码去 “填充” 这些思想准则的具体内涵。
代码规范的真相是什么?
争议与选择
浙公网安备 33010602011771号