浅谈领域驱动设计DDD


title: 浅谈领域驱动设计DDD
date: 2020-08-19 10:19:19


0. 前言

实习期间,组长布置的作业。

1. 简介

2003年,Eric Evans《Domain-Driven Design: Tackling Complexity in the Heart of Software》 一书中提出了 领域驱动设计(DDD) 的重要概念。

如果说 DevOps 是一种软件开发过程的方法,那 DDD 就是一种软件架构设计的方法。

DDD 本质是面向对象分析的方法论,它的革命性在于:利用面向对象的特性,以业务为核心驱动,而不是传统的数据库驱动开发;同时,不同于传统的贫血模型,它提倡充血模型

此处先简单介绍一下贫血模型和充血模型:

1.1. 贫血模型

贫血模型最广泛的应用,应该是在 Spring 框架中,也就是我们常见的 controller/service/model/dao 分层。

这种模型的特点在于:

  • 数据和DB操作分离;
  • 我们在 model 中只实现 getter、setter 方法,而将业务逻辑交给 service 层实现。

可以看出,这种模型的缺点在于:

  • 它将本该聚集在 model 中的业务逻辑泄漏到了 service 中,导致 model 只是一个存放数据的容器,丧失了面向对象的抽象性,其本质依然是一种面向过程的编程;
  • 而且随着项目的演进,sevice 层会十分沉重,业务逻辑会分散到不同的 service 中,代码变得越来越难以理解,并丧失扩展性。

1.2. 充血模型

贫血模型的对立面自然就是充血模型了。

充血模型,提倡将业务逻辑放入 model (领域模型)中,遵循面向对象原则,每个 model 负责自己的业务逻辑。

体现在项目结构中,即是根据业务进行分包。比如:一个订单系统中,最重要的 model 是 product 和 order ,那么项目顶层应该是 productorder 两个包,而不是 controller/service/model/dao 等。

2. 基本概念

领域驱动设计DDD主要包含两方面:战略设计战术设计

战略设计偏向于软件架构,主要关注的是领域和边界上下文的划分。而战术设计偏向于编码实现,主要关注如何用代码实现该领域模型。

通过这两个方面,我们可以更好地理解什么是领域驱动设计:

  1. 领域驱动领域模型的设计
  2. 领域模型驱动代码的实现

2.1. 战略设计

先简单介绍战略设计中的部分概念:

  • 领域:是一种划分,比如:电商平台属于电商领域、金融平台属于金融领域。当然,每个大领域下,还会有许多小领域,比如电商领域下还有:商品、订单、库存、会员等领域。

  • 领域专家:要想理解某个领域的知识,那么我们得找一个对该领域十分熟悉的人,那这个人就叫做领域专家。

  • 领域通用语言:有时候领域专家并不一定是软件开发人员,那么为了方便软件人员与领域人员的交流,就要规定一门领域通用语言。

在战略设计中,一旦系统的主要目标确定,那我们首先就要理解领域知识,让自己成为领域专家;其次,对于一个大领域,我们还需要将其划分成多个小领域;最后,我们还必须再进一步细化每个子领域,比如:明确每个子领域的核心关注点、每个领域之间的关系等。

战略设计就相当于软件开发过程中的需求分析阶段,但DDD更关注于业务而不是数据。

2.2. 战术设计

当战略设计完大致的领域模型后,就该进行战术建模了。

依旧先简单介绍领域模型中的部分概念:

  • 实体:具有生命周期和唯一标识的对象。例如:人就是一个实体,每个人都具有唯一标识(身份证)。
  • 值对象:用于对事务描述而没有唯一标识的对象。例如:颜色信息、地址信息等。
  • 聚合:一些对象的集合,这些对象之间具有高聚合的关系,它们作为一个整体被外界访问,聚合应该尽可能小
  • 聚合根(Aggreate Root):聚合中最主要的对象,例如:会员管理系统,会员便是一个聚合根。同时,聚合根是业务逻辑的主要载体。
  • 领域服务:一些不能归属到任一对象的业务逻辑。
  • 仓库(Repository):将领域模型中的对象持久化到数据库中。

结合上述概念,战术设计的大致步骤为:

  1. 分析领域模型,从中找出实体、值对象、领域服务;
  2. 找出聚合边界和聚合根;
  3. 为聚合配备仓库;
  4. 在工程中实践领域模型,并在实践中检验模型的合理性,倒推模型中不足的地方并重构;

在这过程中,还需要考虑软件设计原则及性能。

当领域建模大致完成后,就需要对系统进行分层架构了。DDD中有如下的经典分层架构:

1.png
  • 用户接口层:主要用于向用户展示信息,并接受用户指令。
  • 应用层:相当于 controller 层,对外提供接口,对内调用领域层,不包含业务逻辑,是领域模型的门面。
  • 领域层:核心层,领域模型所在之处。
  • 基础设施层:为其他层提供通用的技术能力,如:层间的通信、持久化机制等。

在领域层中,包含着系统中的各领域模型,它们以单独的模块存在,相互之间高内聚低耦合。同时,它们也是上文所提到的充血模型。

3. 总结

传统的软件开发习惯,总是从设计数据表开始的,而且大多都采用 controller/service/model/dao 的分层结构,我之前所接触到的项目,基本都是如此。

这种设计开发模式,最大的问题便在于:一旦前期数据表设计不合理,后期的改动则会非常大。

而领域驱动设计最大的优势便在于:软件设计初期关注的是业务,而不是数据表,数据持久化只是设计后期的一个考虑。

就像阿里盒马领域驱动设计实践博客中作者所说的:

假设你的机器内存无限大,永远不宕机,在这个前提下,我们是不需要持久化数据的,也就是我们可以不需要数据库,那么你将会怎么设计你的软件?

脱离了数据库的束缚,面向对象、设计模式等方法是不是可以大展身手了呢?

同时,领域驱动设计所带来的领域划分方法,也与今天的微服务相得益彰。

DDD所提倡的基于业务设计、面向对象分析、基于子领域分治等思想,还是值得借鉴的。

但是我认为,DDD的实践也存在着一些问题,比如:

  • 领域建模得到的充血模型,业务逻辑函数集聚在一个聚合根对象中,是否会导致该对象过于臃肿?
  • 子领域中,面向对象的设计是否会导致问题复杂化,面向过程是否更加快捷方便,特别是像go这种不擅长面向对象的语言?
  • 实体对象如何高效地跟数据库衔接,如何进行复杂的查询?

俗话说,没有最好的只有最合适的。领域驱动设计只是一个流派,并非完美无缺,很多问题可能在实践中才会真正显露出来。就像微服务一样,虽然带来了高内聚低耦合等好处,但也增加了系统的复杂性、带来了服务管理和监控等问题。

在DDD具体的实践中,还需要我们灵活应变。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335