领域驱动设计(DDD:Domain-Driven Design)

Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD网站之一,可订阅DDD专题

过去系统分析和系统设计都是分离的,这种割裂导致:对需求分析设计的结果无法直接落地为代码,而能够运行的代码却无法完整实现业务功能,同时,软件Bug频出,维护升级重写难度大。

DDD则打破了这种隔阂,提出了领域模型概念,统一了分析和设计编程,使得软件能够更灵活快速跟随需求变化。见下面DDD与传统CRUD或过程脚本或者面向数据表等在开发效率上比较:

ddd

DDD革命性在于:领域模型准确反映了业务领域语言,领域语言是每个行业的行话,正如科学需要数学语言;算法需要编程语言;法律需要法律术语;绘画音乐建筑等也有自己的艺术语言,专业领域都有领域语言。

DDD最大好处是:接触到需求第一步是首先理解其领域语言,提炼出领域模型。DDD让你首先考虑的是领域语言(在特定上下文中的含义),落地的代码能直观映射到领域模型。

DDD难点在于Bounded Context(BC:有界上下文/限界上下文),关键是在于"Context":

  • Context:Context is King已经成为现代认知最基本的共识之一
  • Context在中文里或指: 上下文、语境、情况、环境、情境、场景、境地、范围、阶段、局限、背景、周期、顺势、作用域、范式、来龙去脉、路径、道、假设、前提、预设、第一性原理、原因...

中文没有专门Context单词,导致人们忽视其通用广泛存在;另外,认知缺乏边界感也是阻碍之一。

识别上下文是界定问题在哪里,在界定的上下文边界内进行符号推理是解决问题。什么是Context上下文?

DDD是解决复杂中大型业务系统的一套行之有效方式,DDD认为很多原因都会造成软件的复杂性,我们不可能避免所有复杂性,一个好的领域模型是控制复杂性的关键。领域模型的价值在于提供一种通用的语言,使得领域专家、产品经理和软件技术人员联系在一起,沟通无歧义。

DDD 的优势:

  • 对齐:正如桥梁连接两边一样,领域设计驱动确保软件开发与业务领域无缝连接。
  • 灵活性:通过清晰的领域模型,设计驱动发展(DDD)提供了一个基础,可以更好地适应变化,与不断发展的业务需求保持一致。
  • 改进协作:通过建立共享语言,可确保开发人员和领域专家之间的清晰度和统一性。

DDD 有许多组成部分和概念,以下是其中的一些概念:

  • 领域通用语言UL:领域本体语言,业务行话术语,自成逻辑体系的语系,UL是技术和业务沟通的桥梁。
  • BC有界上下文:受专业术语一致限制的形式边界,术语内容含义取决于其语境和上下文。
  • 聚合体:领域模型(实体和价值对象)的对象群,作为一个单一的单元来处理和交易。

banq个人观点:

  • 事件=点、上下文=线、子域=面
  • 线由点组成,建议从事件活动点开始,从下而上涌现中发现上下文。
  • 子域的面由很多上下文的线组成。
  • 由下而上设计流程:点->线->面;而不是由上而下设计:面->线->点
  • DDD建模是一个探索发现过程,无法从顶层设计开始
  • 由上而下是一种科学还原论方法,认为事物由分子组成,分子由原子组成,只要找到所有原子就能组装成任何一个物体,其实很多物体现象是由原子之间相互作用才有的涌现属性,如果拆分成单个原子反而找不到这些属性,1+1>2,大于2的属性不属于俩个1,而是两个1组合在一起才有的。
  • 事物由下而上涌现产生,如果你颠倒次序,由上而下学习复制,你以为这样的复制还是原来的那个事物吗?上下颠倒制造复制一个就是原来的那个吗?这是在做模具吗?不是,世界不是用机械模具复制出来的。

DDD落地架构有:Clean架构、六边形架构CQRS、Event Source几大大相关领域。下图是传统以数据库为中心的架构与使用DDD实现以领域为中心架构的区别。

服务器后端架构发展两个阶段:

  1. UI+Service+DataBase的多层SOA架构(上图左),这种服务+数据表模型的架构易使服务变得囊肿,难于维护拓展,伸缩性能差,见这里讨论Spring Web 应用的最大败笔
  2. DDD+ 模块化单体微服务:DDD作为数据建模的升级,主要贡献在于领域界线的划分,界定界限以后,通过两种架构实现领域模型代表的业务功能:模块化单体或微服务架构。

DDD专门为解决复杂性而诞生,因此解决思路完全不同于传统的CRUD,但是DDD本身掌握起来并不会感觉复杂,从程序员角度看,DDD其实是研究将包含业务逻辑的ifelse语句放在哪里的学问,包括业务流程、业务规则、规则引擎、术语字典、DSL正则表达式、商业智能和数据分析等都属于业务逻辑的范畴领域。

DDD推进过程主要难点是领域发现和领域建模,万事开头难,目前用于领域发现的方法有:事件风暴、业务能力建模、领域讲故事、业务模型画布、示例映射、影响映射、Wardley Maps等,全球DDD社区为此做出主要贡献的人员名单(按Twitter名称排列):

    @ericevans0 创建了DDD
    @ntcoding 发明使用画布canvas 映射有界上下文方法。
    @mathiasverraes 提出了事件溯源具体设计策略,提出复杂系统的仿真建模。

 

教程与文章

为什么要进行领域驱动设计?

板桥大话DDD
用大白话简单谈谈DDD的一些基础特点,只是扫盲!数据库SQL强人慎入

Vladik Khononov:如何学习领域驱动设计? DDD基础新书

《复杂软件设计之道:领域驱动设计全面解析与实战》
博主banq的DDD深入全面书籍

板桥:为什么DDD的Bounded Context翻译为"有界上下文"?

由下而上的领域事件是DDD中由上而下设计的突破口

面向对象建模与数据库建模两种分析设计方法的比较
数据库驱动设计与对象建模是决定软件不同命运的两大派别,谁可以让软件更具有生命,维护拓展更方便?伸缩性更强?

面向对象与领域建模
据调查,目前有70%左右程序员是在使用OO语言编写传统过程化软件,缺乏完整的面向对象思维方法的教育和培训是基本根源,本文对软件开发中几个常见问题提出了独立的见解及尖锐的观点

Evans DDD 领域建模
如何提炼模型,而不是数据表,进而精化模型对象,使其能够反映领域概念基本本质是一个复杂过程,Evans DDD是2004年提出的具备革命性影响的软件思想。

实战DDD(Evans DDD:Domain-Driven Design领域驱动设计)
领域建模是一种艺术的技术,不是数学的技术,它是用来解决复杂软件快速应付变化的解决之道。

领域模型驱动设计(Evans DDD)之模型提炼

软件建模设计

如何从职责和协作中发现丰富的充血对象?
失血模型贫血模型是DDD最大敌人,如何根据SOLID原则GRASP原则设计业务行为?本文给出了DDD具体实践中一些具体细节,是和DDD配合一起进行面向对象分析设计的好方法。

DDD CQRS和Event Sourcing的案例:足球比赛
DDD + CQRS + Event Sourcing实现案例,结合代码与理论讲解。

集装箱车队系统的DDD案例
为上海某大型港口公司的运输系统实施的一个领域驱动设计DDD的实战咨询案例。

DDD仓储实现:Spring Data JDBC教程

不使用DDD的后果:为什么我们停止了向微服务的迁移?

使用DDD聚合发现隐藏的业务规则的案例分析:数据库事务的业务实现 

向领域驱动设计前进: 如何使用DDD实现从单体到微服务迁移打造业务平台或中台?

DDD+微服务大型案例:Uber如何从复杂的RPC微服务转向面向业务领域的微服务架构DOMA?

全球大型电商Shopify如何使用DDD实现单体架构的模块化?

东南亚最大消费App经验:大数据分析为什么大多数会失败?

领域驱动设计实践:支付系统建模 - Xiao

DDD中使用残差理论设计有弹性的上下文BC

本站DDD现场培训视频

更多#DDD领域驱动设计专题

DDD案例实现:开源Jivejdon 文档按这里

相关参考

领域驱动设计之实践与反思

#DDD案例   #DDD有界上下文   #DDD聚合

#DDD实体 #DDD值对象 #DDD服务

#DDD仓储模式 #DDD Specification规格模式

#领域事件 #EventStorming #CQRS架构

#职责驱动设计 #业务分析设计 #工作流BPM