领域驱动设计
《领域驱动设计》是复杂软件系统设计领域的里程碑著作。埃文斯提出了以领域模型为核心的设计方法论,通过通用语言、限界上下文、聚合根等概念,为应对软件核心复杂性提供了系统性的解决方案。
本书速读
《领域驱动设计:软件核心复杂性应对之道》由Eric Evans撰写,是软件架构领域的开创性著作。本书提出了一套应对复杂业务系统的设计方法论,强调软件设计必须紧密围绕业务领域展开。
DDD的核心主张是:对于复杂的业务系统,最重要的不是技术选型,而是深入理解业务领域本身,并在代码中精确表达这种理解。一个成功的软件系统,其代码结构应该直接反映业务概念和业务规则。
本书分为四个部分,分别介绍了将模型与实现绑定、重构的支柱、用模型来统领设计以及战略设计。每一部分都围绕一个核心主题展开,层层递进,最终形成完整的DDD方法论体系。
DDD强调的通用语言概念彻底改变了开发团队与业务专家之间的沟通方式。通过建立统一的术语体系,消除了长期以来技术人员和业务人员之间的"翻译"成本。
在战术层面,DDD提供了实体、值对象、聚合、仓储、领域事件等模式,帮助开发者将业务概念精确地映射到代码结构中,保证领域逻辑的完整性和一致性。
在战略层面,限界上下文和上下文映射帮助我们在大型系统中划定合理的模块边界,管理不同子系统之间的集成关系,让复杂系统保持清晰和可控。
模块1:通用语言——消除技术语言与业务语言之间的鸿沟。
术语一致:在团队内部建立统一的专业术语表,同一个概念在任何地方都用同一个名字,消除一词多义和一义多词的混乱。 消除沟通鸿沟:开发人员、业务专家和测试人员使用相同的语言讨论需求、设计和实现,避免"翻译"过程中丢失关键信息。 模型即语言:领域模型中的类名、方法名直接使用业务术语,让代码成为业务逻辑的精确表达,实现模型与代码的统一。 持续演进:通用语言不是一次性制定的,而是在开发过程中不断精炼和完善的,随着对领域理解的加深而持续演化。通用语言是DDD最基础也最强大的工具,它让代码成为业务逻辑的真实反映。
模块2:限界上下文——划定系统的边界,管理复杂性。
划分系统边界:每个限界上下文包含一个独立的领域模型,上下文的边界就是模型适用性的边界,超出边界模型的含义可能改变。 上下文映射:明确不同限界上下文之间的关系——是共享内核、客户-供应商、遵奉者还是防腐层,选择合适的集成策略。 独立演进:每个限界上下文可以由独立团队负责,使用最适合的技术栈和数据存储,实现真正的模块化开发。 防腐层模式:在集成外部系统或其他上下文时,通过防腐层隔离外部模型的变化,保护内部领域模型的纯洁性。限界上下文是管理大型系统复杂度的关键武器。
模块3:战术模式——将领域概念精确映射到代码结构。
实体:具有唯一标识且在其生命周期中持续存在的领域对象,关注其身份的连续性和不变性,而非属性的具体值。 值对象:通过属性值来定义的对象,没有唯一标识,不可变,用于描述领域中的度量、描述或分类等概念。 聚合:一组作为一个整体进行数据修改的关联对象集合,聚合根是外部唯一可引用的对象,确保聚合内的数据一致性。 仓储:提供获取和持久化聚合根的机制,模拟内存集合的语义,隐藏底层数据访问的复杂性,让领域层不依赖具体的数据库技术。战术模式让领域模型从纸上概念变成可执行的代码。
模块4:战略设计——从全局视角规划和组织系统的架构。
核心域:系统中最关键、最具竞争力的业务领域,应该投入最优质的资源和最有经验的人才,这是系统成功的关键。 支撑域:业务必需但不是核心竞争力的领域,可以内部开发但无需投入顶级资源,保持足够好即可。 通用域:通用的、可以从外部获取的能力,如认证、日志、消息等,应该购买或使用开源方案,避免重复建设。 上下文映射关系:用可视化的方式展示各限界上下文之间的依赖关系和集成方式,帮助团队理解全局架构和协作方式。战略设计让架构师能在宏观层面把握系统的整体方向和资源配置。
💡 金句摘录:
1. "对于大多数软件项目而言,最重要的不是技术,而是领域本身。"
2. "如果代码不能反映业务逻辑,那代码就是错的。"
3. "限界上下文是DDD中最核心的战略模式。"
4. "通用语言让代码成为业务逻辑的真实表达。"
📖 阅读建议:
本书理论性较强,建议配合实际项目阅读。可以先学习通用语言和限界上下文这两个最基础的概念,然后在项目中尝试识别核心域和支撑域。对于初学者,推荐先阅读Vaughn Vernon的《实现领域驱动设计》作为入门,再回头阅读Evans的原著。DDD适合业务逻辑复杂的系统,如果系统只是简单的CRUD操作,不要强行套用DDD,以免过度设计。