从领域驱动设计到模型驱动开发


前言

本篇是在领域驱动设计理论上加以思考后提出的一些观点,适用于对DDD 有一定了解的人员阅读,另外本篇偏向于实践而不是论述理论。请悉知~

1. Domain 层的模型驱动开发

在DDD 的项目上,当我们经历过了事件风暴->命令风暴->划分限界上下文后。我们就会产出一份基本上可以映射至代码实现的领域模型了。这份模型图上已经包含了entity、value object、聚合根等类。且对应的类图上已经有了属性以及实现的方法。我们可以基于这种领域模型很轻松的实现我们的代码。这就是Domain 层的模型驱动开发,我们在实现Domain层的逻辑时,确实是完完整整的参照领域模型里的图来实现代码的。领域模型样例如下图:

Exam System Context.png

当我们有了领域模型后,我们会发现实现Domain的代码是如此简单。它其实是将我们代码设计过程提前了,且可视化出来了。这样能够让大家都有一致的理解,也能够更早的发现问题。

不过值得一提的是,有时候在根据领域模型实现代码时,我们会发现之前在建模时没有考虑到的地方亦或设计不合理的地方。这个时候我们并不会继续照搬模型,我们应该对模型进行重新建模,在没有问题之后再继续实现我们的代码。它就像测试驱动开发一样,是一个双向绑定的过程,我们既能够通过模型分析出设计不合理的地方,也能够在实现模型的过程中发现设计不合理的地方并及时更新模型。它是一个双向验证的关系。

在Domain层,我们已经可以通过之前的领域建模实现出领域层的代码了,但是这些模型并没有指示我们应该如何实现应用层的代码,比如:我们的接口应如何暴露、数据如何存储、和其它系统或服务之间的交互应如何实现呢?我们仅有领域建模来驱动是不够的,所以我们还需要另外一层的模型来驱动开发。

2. Application 层的模型驱动开发

既然我们要使用Application 层的模型驱动开发,那么我们首先要有模型可依,所以我们要先对它进行建模。我们依然使用工具画出我们期望实现的交互方式,这一步的建模就不再需要一个团队来讨论完成了,它是由当前开发某一功能的开发人员来绘制的。这个模型图上描绘了要暴露的功能是什么,要用到的Domain功能有哪些,还会与哪些服务或外部系统来交互等。

当我们完成了Application 层的建模,那么我们就可以按照我们建好的模型进行开发实现了。同样,模型与代码也是一个双向绑定的过程。我们在实现代码时,同样会进行更细致的考虑,当我们发现设计的模型存在缺陷时,我们应重新调整模型,然后再继续开发实现。这样就形成了模型指导开发,开发验证模型是否完备,最终我们会产出一份能够完全映射代码实现的模型与实现的代码。

2.1 Application 层的建模工具推荐

我在实践时一直使用的Plant UML来进行建模,它可以让我们向开发代码一样来编写我们的模型。

强烈推荐使用如下的框架来构建模型,因为它简单易用且模型精美

// import 链接,直接放在文件最上层就可以使用
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Component.puml

2.2 Application 层的建模并不会影响开发效率

我们要认识到一点,我们在对Application进行建模时,并不会影响我们的开发效率,相反,它反而会帮我们理顺思路,减少代码返工以及bug的产生。

因为我们在建模的过程,其实就是开发人员在实现代码前拆分task的过程。有一个可能大家有过的经历,在做一个复杂的功能时,没有提前拆分task,在实现的过程中经常遗漏各种要实现的细节。而现在我们在建模时,就会考虑这些实现细节,待我们实现时,就按照模型上的描述一步一步实现就可以。

2.3 将Application 层的建模保存至代码实现的同一目录下

我们可以将开发阶段建立的Application模型与代码一同存放至Application层,推荐与Controller 放在一起,一个Controller与其对应的多个模型图放在同一个包下。

那么我们为什么要存放这些模型图呢?你们可能会想,如果我们想了解代码怎么实现的话,直接看代码就可以了,何必要多此一举呢?其实不是这样的,下面我们来看一个我真实经历过的例子。

这是一个有关系统的登录功能的开发,我先以流水线的方式叙述一下它的登录功能。

  1. 用户访问登录页面
  2. 前端首先需要掉后端的某A接口获取加密后的第三方单点登录链接来进行前端页面的跳转
  3. 用户在第三方登录完成后,前端会从第三方页面拿到一个code,再次调用后端某B接口来解析Code拿到用户的username在后端校验后并暂时缓存
  4. code解析成功后,用户需要进行短信验证码验证,这时前端又会调用后端某接口C来发送验证码(单拎出来发送验证码的接口是为了重复发送验证码)
  5. 用户输入完验证码后,前端再调用后端某D接口来验证是否正确,至此登录完成。

可以看到,在登录这一流程里,前端总共向后端调用了4次接口,而且在这个过程中前后端的交互是紧密联系在一起的。这4个接口在后端确实放在同一个Controller下,但是我们单看这四个接口的代码实现,并不能清楚的理解到登录的实现流程。况且前后端联系这么紧密,肯定是需要前后端实现一起看才能弄清楚实现的。

这就是一个典型的例子,我们是需要一个模型图来描述我们的逻辑实现的。如果我们在设计之初就构建好了这样的模型图,那么后人在理解起来就容易的多了。

当然我在实现的时候是有对它进行建模的,以下是我当时的模型图,大家可以体会一下模型图的作用。

写在最后

本篇文章在DDD的基础上,讨论了如何利用模型来驱动开发。本文意旨通过模型来反应我们的实现代码,当我们将要对代码发生变动时,我们要先将对应的模型实现,然后再去实现代码。

值得注意的是,模型驱动开发跟TDD有点像,但是它也是一个双向验证的关系,我们是可以通过模型图来反应代码设计的,但是开发过程中,模型图并不是一成不变的,我们有可能会发现一些之前在建模过程中没有考虑到的细节,这时我们需要对现有模型进行调整,然后再进行开发。不过我们要保证在建模期间尽可能的将所有场景都考虑清楚,就像我们开发某一功能前,拆分task一样。

以上就是我有关模型驱动开发的一些观点,大家如有什么观点,欢迎讨论。

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