提炼问题域

提炼问题域

对于复杂问题我们本能的反应会是到一个问题给出一个回应办法,而从这些问题整体来看这种方式会阻碍团队找出最佳解决方案。DDD 帮助技术人员对需求进行本质思考和理解,最大的突破是着重明确了区分了问题域和解决方案域。对业务问题的认知不是技术人员最擅长的,很多研发在碰到需求时,脑子本能就闪现表、类、服务、架构,把解决方案当终极问题来追求,而 DDD 要求研发进行痛苦的蜕变,关注点不在是聚焦在功能上,而是理解需求的真正意图和愿景,更深层次地理解隐含的愿景才能开发出真正地解决问题和创造价值的系统来。

同时 DDD 要求领域专家和技术人员坐在一起通力合作、密切沟通来分析和建模,领域专家对业务有着深刻的理解,技术人员擅长技术实现和架构设计,而领域专家和技术人员由于工种的差异导致交流产生障碍,开发人员满脑子是技术语言,领域专家脑子也都是业务概念,如果按照本能基于自己的专业背景进行沟通,效率太低了,即使有翻译的角色也会产生理解偏差,DDD 的一个核心原则是所有人员包括领域专家和技术的进行任何沟通都使用一种基于模型的通用语言(UL,Ubiquitous Language),在代码中也是这样。在提炼问题域过程中,领域专家和技术专家通过充分交流,进行需求分析和知识提炼,获得清晰的问题子域,识别出核心域、通用域、支撑域。

  • 通用(Generic)层: 通用层通常被认为已经被行业解决的问题,如架构设计中的可观测性的 Logging、Metrics 和 Tracing,各种云服务(Cloud Service)等,这些都已经有比较好的实现方案,对接就可以;如成熟的行业解决方案,如 ERP、CRM、成熟硬件系统等,直接采购即可。

  • 支撑(Supporting) Domain:和通用层类似,但是系统更来自内部或者还需要在通用的基础上进行一些定制开发。如一个电商系统,会员、商品、订单、物流等业务系统,当然还有一些内部开发的技术类型支撑系统。

  • 核心(Core)层: 也就是我们常说的业务核心,当然如果是技术产品,就是技术核心,这个也就是你最要关注的;核心域是开发该软件系统根本竞争力所在,也是领域建模的重心,建议分配最精锐的研发。

核心域是最与众不同且花费精力比较多的,在复杂性 Y 维度,我们要避免高复杂度的通用和支撑层,这样会分散你的注意力,同时还要投入非常大的精力,如果确实需要,购买服务的方式可能最佳。

Model Complexity vs Business Differentiation

该阶段领域专家只专注于问题域而不是解决方案,业务和技术人员基于 UL 沟通,并且考虑投入产出比,团队只为核心业务进行领域驱动设计并创建 UL,订单系统为下单模块进行 DDD,订单监控模块用普通的事务脚本方式来即可。需求分析时从用例开始,列出达成业务目标需要的步骤,切忌跳转到解决方案上,识别出用于构建模型的知识,通过 UML 表示分析模型和业务模型,形成业务和技术人员达成共识的通用语言。

案例:桃树与保险

以研究对象“桃树”为例,其中包括:根,茎,叶 花,果实,种子。这些元素,其中 根茎叶 可放在一起,看做 “营养系统-子域”;,果实,种子 可以看做“生殖系统-子域” 如图:又可细分。

桃树,问题域

我们来看一下上面这张图。这个例子是在讲如何给桃树建立一个完整的生物学知识体系。初中生物课其实早就告诉我们研究方法了。它的研究过程是这样的。

  • 第一步:确定研究对象,即研究领域,这里是一棵桃树。
  • 第二步:对研究对象进行细分,将桃树细分为器官,器官又分为营养器官和生殖器官两种。其中营养器官包括根、茎和叶,生殖器官包括花、果实和种子。桃树的知识体系是我们已经确定要研究的问题域,对应 DDD 的领域。根、茎、叶、花、果实和种子等器官则是细分后的问题子域。这个过程就是 DDD 将领域细分为多个子域的过程。
  • 第三步:对器官进行细分,将器官细分为组织。比如,叶子器官可细分为保护组织、营养组织和输导组织等。这个过程就是 DDD 将子域进一步细分为多个子域的过程。
  • 第四步:对组织进行细分,将组织细分为细胞,细胞成为我们研究的最小单元。细胞之间的细胞壁确定了单元的边界,也确定了研究的最小边界。

我们知道细胞核、线粒体、细胞膜等物质共同构成细胞,这些物质一起协作让细胞具有这类细胞特定的生物功能。在这里你可以把细胞理解为 DDD 的聚合,细胞内的这些物质就可以理解为聚合里面的聚合根、实体以及值对象等,在聚合内这些实体一起协作完成特定的业务功能。这个过程类似 DDD 设计时,确定微服务内功能要素和边界的过程。结一下,就是说每一个细分的领域都会有一个知识体系,也就是 DDD 的领域模型。在所有子域的研究完成后,我们就建立了全域的知识体系了,也就建立了全域的领域模型。

保险是个比较大的领域,很早以前的保险核心系统把所有的功能都放在一个系统里来实现,这个系统就是我们常说的单体系统。后来单体系统开始无法适应保险业务的发展,因此保险公司开始了中台转型,引入分布式微服务架构来替换原来的单体系统。而分布式微服务架构就需要划分业务领域边界,建立领域模型,并实现微服务落地了。

为实现保险领域建模和微服务建设,我们可以根据业务关联度以及流程边界将保险领域细分为:承保、收付、再保以及理赔等子域,而承保子域还可以继续细分为投保、保全(寿险)、批改(财险)等子子域。在投保这个限界上下文内可以建立投保的领域模型,投保的领域模型最后映射到系统就是投保微服务。这就是一个保险领域的细分和微服务的建设过程。那么你可能会说,我不是保险行业的人,我怎么理解这个过程呢?我认为,不同行业的业务模型可能会不一样,但领域建模和微服务建设的过程和方法基本类似,其核心思想就是将问题域逐步分解,降低业务理解和系统实现的复杂度。

下一页