写点什么

8x Flow 业务建模法(一):你能分清业务和领域吗?

用户头像
胡皓
关注
发布于: 2021 年 04 月 02 日
8x Flow 业务建模法(一):你能分清业务和领域吗?

本文原文发表于我的个人博客:

https://huhao.dev/posts/2932e594/

前言

最近两年,以“事件风暴(Event Storming)”为代表的“领域驱动设计(Domain Driven Design,以下简称 DDD)”分析建模方法红遍大江南北。伴随着按照 DDD 思想指导微服务拆分的流行,“搞微服务必用 DDD,用 DDD 必做事件风暴,写代码必用六边形架构”的做法已几乎成为了某种所谓的“最佳实践”。


虽然我们一边反复强调“DDD 不是银弹,事件风暴也不是 DDD”,但是还是眼睁睁的看着 DDD 被用成了银弹,用了事件风暴也被等同于做了 DDD。


这两年,我也做了不少 DDD 的实践和咨询服务,也写过一些文章和组织过 DDDChina 峰会上的工作坊。但是在持续的解决不同的客户需求的过程中,确实经历了一个从“忽视到真香,再从真香到疑惑”的过程。其中在使用 DDD 和事件风暴的过程中,经常困惑的一些典型案例(也是经常被问到的问题)包括:


  • 数据类应用的设计和开发如何应用 DDD 思想?

  • 客户交易系统和 GIS 这样的系统,DDD 应用上有何区别?

  • 很明显的流程类功能或系统适合 DDD 吗?还是用个工作流引擎就完了?

  • 以上这些系统的分析建模都能应用事件风暴吗?还是说可以用其它方法?


如果一定要收敛一下以上的问题,那就是经常会被大家问到的一句话:


问:“DDD 到底在什么情况下适用什么情况下适用?”答:“业务逻辑复杂的系统。”


DDD 的这个回答就很诡异了——**到底什么是业务逻辑?到底什么是复杂?**这回答面对上述 4 个问题基本就等于什么都没讲。


虽然我在之前的实践中,尝试过进行更加明确的说明,但是在业务和复杂性的关键定义上,基本上没有质的变化。我的相关解释请参看:《领域驱动实战思考(二):用分段思想改进那些混乱的战略设计和战术设计》


换句话说,我认为 DDD 并没有真正的清晰定义和解答什么是“软件核心复杂性”,而是绕过了这个关键点,认为“问题都需要澄清和定义”,然后在所谓“战略设计”和“战术设计”的包装下,打着“澄清问题”的旗号,直接切进了“统一语言”和“协作设计”,以及系统架构和实现细节——有一种“别问,问就是需要澄清”的甩锅嫌疑。


而遗憾的是,在持续多年的修修补补之下,DDD 的这个核心问题却丝毫未被解决。


那么,到底有没有什么方法能对于以上问题(业务、领域、复杂性)做出相对更加清晰的澄清和解答呢?


幸运的是,在和 ThoughtWorks 中国区 CTO 徐昊一起推动本公司工程效能变革的过程中,我了解并学习到了一套基于徐昊对于软件工程和架构设计多年的实践和思考,由他总结沉淀的,从“四色建模”所发展出来的,被称之为“8x Flow”的业务建模方法,有效的解答了我的困惑。


在此,我将利用一系列文章,将相关的思想、方法和配套的工程效能实践分享给大家,希望能够对大家有所帮助,同时也希望得到更多的碰撞和反馈。


8x Flow 核心思想

在介绍基于 8x Flow 的业务建模过程之前,大家需要先了解 8x Flow 背后的关键思想。


(有关于徐昊本人对于这些思想的说明,我作为参考资料附在了文章结尾,欢迎大家参阅。在此,更多的是基于我与徐昊的多次讨论和我个人的理解,来向大家予以介绍。)

业务逻辑与领域逻辑分离

首先,我们来关注什么是“业务逻辑(Business Logic)”,什么是“领域逻辑(Domain Logic)”。


在 DDD 的解释中,“领域”指的是:


Domain: A sphere of knowledge, influence, or activity. The subject area to which the user applies a program is the domain of the software.(领域:知识、影响或活动的范畴,用户应用了程序的主题领域就是软件的领域。)—— 2015,Eric Evans《Driven Design Reference》


这句话有点拗口,但是通常大家对于 DDD 所说的领域的白话理解就是:


领域就是问题的集合。


然而,徐昊在 8x Flow 中对于“业务”和“领域”进行了更为清晰的区分和解释,即:


业务逻辑:源自业务运营的逻辑,是领域中立且运营特定的,其复杂度来自于流程本身,关注的是如何盈利和成本结构(或者可以理解为对外体现为利润或现金,对内体现为成本和绩效承诺),常见于:合同、法务、会计、审计等。


领域逻辑:源自问题域的逻辑,是运营中立而领域特定的,其复杂度来自于问题本身,关注的是如何解决问题,常见于:算法、计划、统计、优化等。



直接看以上定义可能并不好理解,让我们基于一个简单的医院门诊就诊流程,通过事件风暴和以上解释的视角区别来看一下。


下图为我们接下来要用到的医院门诊就诊流程:



如果我们使用事件风暴来进行 DDD 分析建模的话,基本上会围绕事件得到如下的分析结果:



我们会发现,以上事件风暴的分析结果和原始流程看起来似乎没有什么不同,只是更多的关注了每一步的结果。


但是按照 8x Flow 对于业务和领域的区分视角,重新分析这个就诊流程的时候,就会发现,按照前面所说的业务和领域的定义进行分别标注,其实这个流程中的不同过程,是不一样的:



为什么是这样呢?我们来拿其中的几个环节来说明一下。


回顾之前的定义,“业务逻辑的复杂度来自于流程本身,关注的是如何盈利和成本结构“,在现实中,其实更多的关注的是甲乙双方,基于某种具有权责关系的合作约定的过程凭证留存和追溯


那么大家脑补一下门诊就诊这件事,这里面门诊挂号单、检查单、检查报告……等等这些单据,就是现实中(假设没有 IT 系统)非常重要的“可追溯业务凭证”。


那么我们再看“领域逻辑的复杂度来自于问题本身,关注的是如何解决问题”这件事儿,结合门诊流程来看,那么门诊如何挂号(线下还是线上,窗口还是挂号机),医生如何根据其专业技能和经验进行检查和诊断……等等,其实就是非常复杂和专业的“如何解决问题”。


说了这么多,区分了这两种不同的逻辑,到底有什么用呢?


当我们把这两种逻辑从图像上进行显式的区分后,就能看出来有什么不一样了,见下图:



图中灰色的部分就是业务流程(业务逻辑),而每一个领域(领域逻辑)则是形成业务流程中每一个“可追溯业务凭证”的具体过程(可以想象一下“计算结果”和“算法”的区别,虽不准确但可以感觉出来)。


有经验的架构师会明显的发现,以上例子中,所分析出来的业务逻辑和领域逻辑,具有明显不一样的变化原因和变化频率,如果不能理解的话,可以想象一下折扣总额(业务)和促销活动(领域)。


那么,反观 DDD 和事件风暴现有的分析和建模方法,如果我们都不能识别业务和领域的明显的变化边界,那如何能够有效的隔离变化呢?


识别并区分业务与领域的变化边界,这是 8x Flow 的第一个显著的优点。


除了这个优点之外,对于架构设计来说,有什么样的好处呢?我们来对图片做个小小的调整,将领域变成“接口(Interface)”:



铛铛!有没有发现所有的 Domain 都可以是系统架构的扩展点?从而实现可替换?


从这里也能看出一个道理,往往业务的变化相对较慢,而领域的变化,是可以很快的。


通过抽象领域逻辑,提升业务系统的可扩展性和灵活度,这是 8x Flow 的第二个显著优点。


最后,结合以上两个优点,我们再来回顾一下门诊就医这件事情。


医院的业务,就是提供医疗服务,与盈利有关,他的业务模式是相对比较稳定的:挂号、检查、出具检查报告、出具诊断书、出具处方笺、拿缴费单缴费、拿缴费证明取药……


不论是看眼科、特诊科还是骨科,医院的业务流程是不变的,而具体要看哪个科室,医生怎么看病出诊断等等,都是领域专有的问题。


正是因为业务的相对稳定和领域的可变性,才共同建立起了医院的多样化医疗服务。

分离了,然后呢?

到现在,应该把什么是业务什么是领域这个问题说清楚了,但是然后呢?分的这么清楚,除了前面所说的隔离变化和识别扩展点,还有什么用呢?


这里,其实特别要说的就是我的感受最为重要的一个:


业务与领域分离后,能够让我们分清问题,并应用不同的分析、建模和设计方法,防止出现把单一方法论当银弹。


首先,针对业务逻辑,历史上有过多种分析建模法,其中更加贴近“业务可追溯性”的一个就是四色建模,而通过徐昊的改良后,我们可以采用 8x Flow 实施更加套路化的业务分析和建模。


这里需要强调一下,我们后面介绍的 8x Flow 只适合业务建模!只适合业务建模!只适合业务建模!


而领域系统的分析、建模和设计就很特别了,因为没有唯一方案。


这是因为不同的领域问题往往是”专有的“,具备很强的专业性质,解决这些问题的时候,通常需要以下几种解决方法:


  1. 相关问题可以找到行业内已有的解决方案,拿过来直接借鉴即可;

  2. 需要依据专业研究或领域专家经验,结合研究成果和经验来设计解决方案;

  3. 没有已知解决方案,需要不断的调整和尝试。


在通过软件解决领域问题的时候,连编程范式都不是唯一的,例如要按需选择是使用面向对象还是函数式编程语言进行实现。


通常来说,当遇到一些领域系统的时候,如果想用 DDD 和事件风暴来分析建模的话,一定会犯难,例如:


  • 数据处理模块

  • 算法引擎

  • 工作流

  • 地理信息系统(GIS)


说了这么多,其实就是想说:


当面对一个软件系统的时候,请不要一上来就 DDD 拆微服务,麻烦先搞清哪里是业务,哪里是领域。


当然,我也不是说 DDD 和事件风暴不能用,就拿我来说,我这俩也玩儿的挺溜呀,武器库里多一些兵器来解决不同的问题不好吗?


PS:当遇到大规模、无共识、技术复杂度不高、同时又不知道还有啥别的更好的方法的场景时,我觉得事件风暴这种建模过程还是能尝试用的,毕竟相对比传统的面向对象设计更套路化一点。

结尾

这一篇文章,重点在于说明业务与领域的区别,算是热热身。我会在后续的文章,逐步为大家介绍如何对于业务进行分析,并使用 8x Flow 进行建模。


在此,先给出 8x Flow 建模的一个例子仅供提前过过眼瘾(和以上门诊就医无关):



而下一篇,我会来讲讲如何通过“合约上下文”分析并提取业务逻辑,敬请期待。

参考资料



欢迎关注我的个人公众号

微信搜索:枪炮与代码,或者搜索公众号 ID:guns_n_code



发布于: 2021 年 04 月 02 日阅读数: 227
用户头像

胡皓

关注

ThoughtWorks首席咨询师 2019.08.29 加入

十年以上软件开发工作经验,从士兵成长起来的软件技术顾问。当前,正深耕于以演进式架构、领域驱动设计、云原生、微服务为代表的数字化架构能力,帮助客户实现软件工程能力提升和数字化转型的目标。

评论

发布
暂无评论
8x Flow 业务建模法(一):你能分清业务和领域吗?