您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

再谈领域驱动设计

时间:2020-11-19 09:54:32  来源:  作者:

本文从需求分析到API设计,试图描述领域驱动设计的过程及思想。同时也能看的出领域驱动设计并不是孤立存在的,它为解决开发团队和业务人员之间沟通而生,进而驱动微服务的划分以及API的设计。

作为一个领域驱动设计的实践者,我切实感受到了领域驱动为软件开发带来的好处,同时在实践领域驱动的过程中也感受到了困难,这种困难体现在工程实践的方方面面,例如什么是领域驱动的最佳设计?如何把书本上的设计灵活的应用在自己的项目上?如何跟团队成员就设计达成一致?

本文尝试从领域驱动设计的目的出发,试图通过简单的描述来说明领域驱动设计的思想。

为什么需要领域驱动设计

作为一个软件开发者,多数人以为自己的职责就是编写代码,然而软件开发不是工厂流水线,如果所有的软件开发者不停的开发新功能而不关心设计,那么软件开发过程将会变得越来越复杂,关于这一点大家应该都有不同程度的感受。

软件开发工程师的工作是通过软件来解决问题,编写代码只是其中的一部分工作,设计和交流同样重要。而领域驱动设计就是一个让软件开发工程师交流和共享领域知识的途径。

再谈领域驱动设计

 

共享领域知识的重要性

作为一个问题的解决者,能否理解和认识问题的前因后果至关重要。很明显,如果你只看到了问题的表面,或者对事实有曲解,你显然不会找到一个有效的解决方案。对于开发者,如果你编写的代码只是你的理解,而不是领域专家的理解,你如何保证线上产品的质量?

那么如何保证开发者编写的代码就是领域专家的想法?最简单的办法就是让领域专家来编写代码,但是这种方案可遇不可求,还有没有别的办法呢?

如果领域专家,开发团队以及代码能够共享一个模型,这将有效减少不同利益相关者的沟通及交流,并且会确保所有人都在解决同一个问题。

这个想法要求开发者能够把代码设计为一个反映业务的模型,而这正是领域驱动设计的核心思想。

再谈领域驱动设计

 

通过业务事件来理解问题域

为了在领域专家和开发者之间建立一个共享模型,收集需求并理解业务是第一步。收集需求和理解业务的方式多种多样,而事件风暴经常被用来达到这一目的。业务逻辑可以看做是一系列状态的转换过程,而这些过程转换又被称为领域事件。比如“订单已提交”就是一个领域事件,如果把这个领域事件看做是订单业务的开始,通过梳理”订单已支付”以及”订单已出库”等后续的领域事件,就可以理解整个订单业务。此时对业务的理解被称为“问题域”。

再谈领域驱动设计

 

把问题域划分为问题子域

通过事件风暴,开发团队和领域专家已经对整个”问题域”有了理解,但是现在着手解决“问题域”还有点早。当我们在面对一个大的问题时,自然而然会想到先将大的问题划分成若干个小问题,然后再考虑各个击破。接下来的一步就是把大的问题域划分为若干个小的问题域。我们有一个网上商城的问题域,能不能把它分割为更小的问题域?

答案肯定的,我们把网上商城的问题分为:“订单”,“销售”,“市场”,“财务”,“采购”等若干个小问题域,再针对小的问题域分而治之。小的问题域在领域驱动设计中被称为“问题子域”。

再谈领域驱动设计

 

使用限界上下文创建解决方案

理解了问题域并划分为问题子域并不意味着你就能创建出一个好的方案,你无法针对问题子域的所有信息设计出一个解决方案,你的解决方案只会专注于那些有助于解决该问题子域的信息,对于不相关的信息则会人为的屏蔽掉。

为什么叫限界?

在现实世界中,领域的边界很模糊,但是要设计一个好的解决方案,我们需要对问题子域加上一个边界,将不重要的信息排除在边界外。让解决方案专心解决重点问题。

为什么叫上下文?

每个上下文都代表着该解决方案的专业知识。在同一个上下文里,我们共享统一的语言和一致的设计。

通过界限上下文人为将问题子域限制在有限的界限内,你才可以着手创建解决方案。

再谈领域驱动设计

 

创建统一语言

团队之间共享的术语和词汇被称为统一语言。统一语言用来定义业务领域的共享模型,当然可以用在项目的任何地方,包括需求分析和设计,最重要的是统一语言还需要出现在代码中。另外,统一语言在不同的界限上下文中往往不能够通用,例如在“认证上下文”中提到“用户”,在“机票订单上下文”中叫做“乘客”。

领域建模

有了界限上下文,让解决方案聚焦在最有用的信息里,你才可以着手建立共享模型。

如何才能建立一个不错的共享模型呢?

使用可视化的图示似乎是一个不错的想法,但实际上画出一个能够表达所有领域知识的图示并不是一个简单的工作;如果你有数据库开发相关的经验,你可能会想到通过表和主外键来表达领域知识,如果你有这样的想法那你就错了,在领域驱动设计中讲究通过领域逻辑来驱动设计和开发工作,而不是通过数据库模型来驱动开发。

在领域驱动设计中这一步叫做”领域建模“,你应该用代码建立一个反映领域知识的模型,这个模型跟领域专家口中的领域知识是一致的。领域模型是提供业务能力的核心部件,也是整个应用程序提供业务能力的核心。

再谈领域驱动设计

 

领域建模中的其他概念

对于开发者而言领域建模至关重要,也是最考验开发者功底的一个环节。一方面开发者需要抽象出一个跟领域专家口中一致的模型,另一方面开发者还需要通过代码将这个模型表达出来。你需要恰如其分的使用一些面向对象的技巧把领域知识抽象到一个代码模型中,在这个过程中你需要了解”值对象”,”实体“,”聚合根“等概念,在此不再细说。

领域模型的持久化

在领域建模以及之前的步骤中,我们都没有提及数据库,因为领域驱动设计的核心是用代码建立一个共享模型,而数据库设计根本就不是领域驱动设计关心的内容。

但是终究我们还是要把领域模型的状态持久化到数据库中,有没有办法在不关心数据库表结构的情况下,将已经建立好的领域模型持久化?主流ORM的Code First恰好匹配我们现在的处境,已经有一点为领域驱动设计而生的味道了。

但是即便是ORM的Code First也会对领域模型有侵入,你可能需要根据不同的ORM为模型加上一些注解或者配置之类的代码,这跟领域驱动设计其实是相互违背的,我们希望用代码创建一个纯净的领域模型,这个模型封装着领域专家的领域知识,除此之外的代码都跟领域模型是无关。

领域事件及事件溯源

解决上面问题的思路是引入领域事件和事件溯源。领域模型在提供业务能力的过程,就是领域模型状态发生变化的过程。一旦领域模型的状态发生了变化,就会产生一个事件,这跟事件风暴中提到的业务事件是一致的,例如”用户已下单“。订单模型在提供”用户已下单“的业务能力后发生了状态变化。事件溯源的思路就是只持久化领域事件,然后通过还原事件的方式将领域模型还原在最新的状态。

通过采取事件溯源,就可以将领域模型持久化跟数据库完全解耦。

再谈领域驱动设计

 

微服务和领域驱动设计

我们通过领域驱动设计的思路来分析和发现问题域,通过分解把问题域划分为问题子域,通过人为加限制的方式将问题子域转换为限界上下文。而这个过程就是我们分解微服务的过程,一般来说每一个限界上下文都可以映射为一个微服务,但也不是绝对的,具体情况具体分析。

再谈领域驱动设计

 

微服务的交互和集成

每一个微服务专注于解决对应的限界上下文中的问题,并不代表微服务之间没有交流。单个微服务的领域模型在提供服务的过程中会产生领域事件,领域事件为基于事件驱动(Event based)的微服务集成提供了基础,如果在微服务之间架设一条消息总线(不同于ESB,ESB被认为是反模式)。不同的微服务将自己产生的领域事件广播在消息总线上,微服务之间通过订阅自己感兴趣的事件就能完成微服务的集成。

再谈领域驱动设计

 

HATEOAS和领域模型

迄今为止我们已经建立了领域模型,创建了微服务,通过消息和领域事件完成了微服务的集成。还需要把微服务的能力通过REST API展现出来,微服务在对外提供能力的过程就是领域模型状态发生变化的过程,如果将领域模型理解为一个设计精良的状态机也一点不为过。如果设法将领域模型在某个状态下能够提供的能力通过REST API的的返回结果表达出来,这就是HATEOAS的核心思想。REST API不但可以提供某种能力,还可以告诉消费者此时领域模型能够提供的其他能力。

再谈领域驱动设计

 

结束语

本文从需求分析到API设计,试图描述领域驱动设计的过程及思想。同时也能看的出领域驱动设计并不是孤立存在的,它为解决开发团队和业务人员之间沟通而生,进而驱动微服务划分以及API的设计,领域驱动设计并不是遥不可及的方法论,每一个专业术语和思想都是为了解决基本的问题而定义,希望本篇博客能够带你走入领域驱动设计。

文/ThoughtWorks张阳



Tags:领域驱动设计   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
DDD:指领域驱动设计,是domain driven design的缩写。介绍DDD基础知识的相关文章很多,本文就不普及相关的基础知识了,基础理论知识可参考如下文章: 《DDD基础知识与总结》 《DDD...【详细内容】
2021-10-28  Tags: 领域驱动设计  点击:(46)  评论:(0)  加入收藏
在领域驱动架构中,通常会将查询和命令操作分开,我们称之为CQRS(命令查询职责分离Command Query Responsibility Segregation)。这张图是来自Martin Fowler大师的文章CQRS( http...【详细内容】
2021-07-30  Tags: 领域驱动设计  点击:(132)  评论:(0)  加入收藏
领域驱动,各自只管各自的模块,顶层再来进行组装和分配...【详细内容】
2021-06-25  Tags: 领域驱动设计  点击:(92)  评论:(0)  加入收藏
本文从需求分析到API设计,试图描述领域驱动设计的过程及思想。同时也能看的出领域驱动设计并不是孤立存在的,它为解决开发团队和业务人员之间沟通而生,进而驱动微服务的划分以...【详细内容】
2020-11-19  Tags: 领域驱动设计  点击:(93)  评论:(0)  加入收藏
本项目是基于小编的开发经验与心得,分享小编关于领域模型的理解, 个人愚见仅供参考,希望能为渴望进步的你提供帮助。如果你感到有用对你有帮助,请不要吝啬你的关注,求关注,...【详细内容】
2020-07-19  Tags: 领域驱动设计  点击:(36)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条