【深度】领域驱动设计的实践

简介: 关注公众号“达摩院首座”,了解开发者最真实生活

前两篇本座依次讲了DDD的上层设计和下层设计,或者叫战略设计和战术设计。今天来讲实践,其实之前小编写的一篇【大数据】事件驱动的微服务架构一定程度上也是DDD的一个现实案例。对于程序员来说,软件设计是学习业务领域的过程,代码只是附带产物。在程序员和领域专家沟通时,通常会使用用例图、行为图、序列图或ER图来表示对象之间的逻辑关系。

1.jpg

确实,如上一讲所提到的,每一个功能域的模型设计需要领域专家和技术人员不断碰撞出火花,而这个火花是理解子域中的每一个事件(Event)。如果群体讨论可以成为头脑风暴,那基于领域事件的头脑风暴也可称之为事件风暴(Event Storming),通过事件风暴的方法可以快速分析复杂业务领域,完成领域建模的目标。在活动中,团队先通过头脑风暴的形式罗列出领域中的所有的领域事件,整合之后形成最终的领域事件集合,然后对于每一个事件,标注出导致该事件的命令,然后再为每个事件标注出命令发起方的角色,命令可以是用户发起的,也可以是第三方系统调用或者是定时器触发等。最后对事件进行分类这里出聚合根以及有界上下文。

事件风暴的参与人员主要就是上述所讲的业务领域专家与技术人员,预期产出是经过分类的事件的相关属性(包括触发动作Command,统计方式Aggregate,用户角色User Role,视图View、处理规则Policy等等),在事件风暴的时候用便利贴的形式贴在讨论版上。

2.png

这些对象通过事件关联在一起,比如网购的领域模型可以拆解为用户“浏览商品”事件-->“购买商品”事件-->“确认订单”事件-->“物流”事件,每个事件有各自的关联触发动作、用户角色分配、统计方式、视图、处理规则等等。然后根据事件的相关性形成子域模型,例如上述事件可以组成为“商品目录”、“订单”和“配送”三个子域,也就是网购领域的DDD下沉设计,然后每个子域中的各个事件和相关对象就形成了各个子域的微服务架构。

3.png
其实在很多互联网公司我们都可以看到DDD的事件风暴,国外的GAFA和国内的BAT,在考虑共享复用和用户故事的时候,都会整版整版地讨论事件流和事件地图。

4.jpg

接下来进入代码层面的讲述,捋清事件逻辑后,代码就是水到渠成的事,以上面网购中的物流领域为例,某商家策略是购买一定数量的产品后可以免运费,对于未满足数量要求的订单,邮费可以有普邮和EMS的选择。

我们来看下面一串代码,如果放在大学编程课上,这段代码会是一个满分作品,逻辑清晰,思维缜密。但作为领域驱动设计的代码而言,它让非技术人员摸不着头脑,没有表述功能。
5.png

首先,红色部分,这些数字的含义是什么;橙色部分,重复的代码段;绿色部分,BigDecimal对应的原始类型是什么;蓝色部分,公类私类对象错误;紫色部分,i即时作为常用参量,对非技术人员不具备可读性。
此外这段代码还有很多数字不明的地方(就是因为直接使用了数字,导致复用性和可读性都很低),例如:

6.png

下面我们来看下在DDD中干净,可读性强的通用语言代码是怎样的。
7.png

这段代码几乎无需多做解释,就通俗易懂哪怕是跟业务人员交流,而且把参数定义全部抛到前端提供了“类中台”层的能力接口。其实很多开发人员并不是做不到代码的通俗易复用,只是在很多时候,由于开发工期的要求,没有考虑到业务逻辑在多场景下的通用性,甚至有种腹黑的说法是“代码乱到只有自己看得懂才是公司不可替代的人才”。呵呵~

总结下,大到城市规划,小到代码规范,我们都可以用领域驱动的方法论来设计。其重心在于:

战略着眼,战术着手:合理高效的拆分领域是成功的关键;

抓大放小,突出优势:找出公司自身与同业的竞争优势,倾力这些核心子域;

业务驱动,超脱技术:不要将商业问题归咎于技术能力,C++解决不了的问题Python同样解决不了。

规范引领,统筹建设:尽快形成企业内部的技术规范,提高业务复用能力。

相关文章
|
设计模式 缓存 自然语言处理
DDD领域驱动设计如何进行工程化落地
DDD领域驱动设计到底如何进行实际的工程化落地,为什么要进行领域分层?本文主要围绕DDD领域分层,设计了可落地的工程结构。
DDD领域驱动设计如何进行工程化落地
|
缓存 前端开发 中间件
DDD 领域驱动设计落地实践系列:工程结构分层设计
前面几篇文章中,笔者给大家阐述了 DDD 领域驱动设计的三大过程,重点围绕如何通过战略设计与战术设计进行 DDD 落地实践进行了详细的讨论,但是还没有涉及到工程层面的落地。实际上所有的这些架构理论到最后都是为了使得我们代码结构更加清晰,从而开发出 bug 少、扩展性强、逻辑清楚的应用。因此本文就是为了解决 DDD 领域驱动落地实践最后一公里问题,将我们分析出来的领域模型通过与工程结构的映射实现真正的落地。
DDD 领域驱动设计落地实践系列:工程结构分层设计
|
前端开发 Java 数据库连接
领域驱动设计:从学习到实践(一)
产品同学将需求分析完和开发同学进行需求评审,评审完毕后开发同学开始基于需求进行设计,一般会落到数据库设计,将库表设计完毕后,再向上进行分层开发。如果是前后端分离的项目,会在前期约定接口,进行基于契约的并行开发。所以,我们称这种方式为数据驱动开发,或基于数据模型的开发。
领域驱动设计:从学习到实践(一)
|
Cloud Native 架构师 Devops
云原生时代领域驱动设计(DDD)的价值——从《没有银弹》说起
软件开发需要面对本质困难和附属困难。云原生、DevOps实践大幅降低了附属困难,使得架构师可以全力聚焦于业务复杂性,而DDD恰是管理业务复杂性的有效方法。
1589 0
云原生时代领域驱动设计(DDD)的价值——从《没有银弹》说起
|
6月前
|
存储 自然语言处理 前端开发
软考实践之分层架构思想的理论和应用实践
软考实践之分层架构思想的理论和应用实践
301 0
|
数据可视化 Java 测试技术
程序员技术精进:业务分析与设计,领域驱动设计与模型实践
领域驱动设计是一种将实现连接到持续进化的模型中来满足复杂需求的软件开发方法,通过将软件的相关部分连接到不断发展的模型中来简化复杂应用程序的创建流程。领域驱动设计侧重于以下三个核心原则。
|
设计模式 供应链 测试技术
架构进阶之路:复杂业务开发与领域驱动设计
以下是在现公司,给成员做分享的资料。业务案例来自:一文教会你如何写复杂业务代码。作者:张建飞,进行了重新整理。
250 0
|
消息中间件 运维 前端开发
DDD实战之六:战略设计之技术决策
DDD实战之六:战略设计之技术决策
DDD实战之六:战略设计之技术决策
|
存储 设计模式 前端开发
浅谈领域驱动设计实践——董炎焱
近年来领域驱动设计(Domain Drive Design)大火。那么我们为什么要学习领域驱动设计,它适合用于哪些场景?怎么去用?在用的过程中,又有哪些需要注意的地方呢?
浅谈领域驱动设计实践——董炎焱
|
领域建模 微服务
领域驱动设计总结——落地与思考
本文为领域驱动设计系列总结的第六篇,主要对领域驱动设计概念做个介绍,本系列领域驱动设计总结主要是在Eric Evans 所编写的《领域驱动设计》 一书的基础上进行归纳和总结。 本文也是领域驱动设计总结系列最后一篇,主要是简单的探讨下,领域驱动设计的落地方式,以及对这整个系列做一个总结。
350 0