写点什么

领域驱动设计 101 - 绑定模型与实现

用户头像
luojiahu
关注
发布于: 2021 年 03 月 27 日
领域驱动设计101 - 绑定模型与实现

在前面的讨论中我们已经至少明确了如下两点:


  1. 在复杂应用软件设计过程中,需要形成一定形式的领域模型,用于反映实际业务领域的关键信息,并通过结构化组织,揭示领域中对象间的关系。

  2. 从提出实际业务需求到开发出可用的应用软件,业务专家和开发人员之间应该保持密切沟通,通过相互协作来设计应用软件。最好,他们应该在同一个团队里面开展工作,这样能最大限度降低沟通成本,并为系统向成熟演化提供可能。


我们强调了模型的重要性,同时也通过分析组织结构检视了软件设计的过程。下面我们需要进一步对软件设计过程与模型的关系进行讨论。

模型驱动设计


前面已经多次提到了分析设计的概念。这里我们得首先明确:


软件分析与设计应该被视作两个阶段,他们有各自的重点。

分析阶段:通过整合对实际业务领域的认识,识别提炼关键信息以及他们之间的关系,形成领域模型。

设计阶段:通过领域模型获得对业务领域的关键认识,同时补充必要的细节知识,在此基础上,采用一定的工具和方法将模型转化为开发系统所需的软件设计。


现实当中,经常见到两种情况:1. 设计阶段缺失;2. 模型与软件设计脱节

设计阶段缺失


在不成熟的组织或者软件开发过程中,经常看到设计阶段缺失的情况。作为其结果,这经常体现为最终的系统并不能有效解决用户的实际问题、开发过程中需求的反复修改以及整体上经常出现的返工。


不难理解,由于设计阶段的缺失,并未建立起对实际业务领域的全面认识,进行软件设计与开发的知识基础往往是零散或者幼稚的,反复及返工就并不足为奇。即使最终的成品,也很难保证如实反映了业务领域的本来面目,因而其对用户的价值也不能保证。

模型与软件设计脱节


在更成熟的组织中,软件设计阶段虽然被重视,但还会面临另外一个问题:模型设计阶段与软件设计阶段相互脱节。


这种情况通常有如下表现:


  • 模型虽然忠实地反映了业务领域的问题,但是并未考虑技术实现,导致难以落地。


经常听到开发人员抱怨业务的需求难以实现,就可以归为此类场景。曾经在一个初创系统的需求讨论会上,当所有主要的业务流程讨论完之后,业务希望系统能够给予操作员及时的反馈,从而提出系统能够给操作员发短信。这本是一个非常合理的业务需求,也如实的反映了操作员期望得到及时反馈的真实问题。但是,对于一个初创系统来说,虽然“发短信给操作员”这个需求非常简短,实现的成本却非常高。除了需要额外提供操作员的通讯信息的功能之外,还需要调用运营商的服务发送短信,这至少需要建立网关、短信转发服务两个应用来实现。很显然,一个初创系统其核心关注点并不在此,而且这项功能的成本也显得过高了。


为了避免这种情况,业务专家只有和软件设计人员保持密切沟通,互相同步信息,保持专注在核心问题领域上,并且充分考虑技术实现的可落地性,才能产出实际可用的业务模型。


  • 在设计阶段,模型被抛到一边,并未被用来指导设计。


很多时候,虽然建模人员提供出了一个完整的模型,软件设计人员会由于惯性思维将业务需求进行自己的翻译,翻译后的模型可能更加容易实现,从而形成了偏离实际需求的软件设计。我们经常看到,对于一个新来的需求,开发人员总是倾向于采用系统现有的模式、数据结构来实现,这往往体现为在代码中添加一个额外的分支,在数据表中增加一个冗余字段等等。一段时间内,开发人员可能还能够记得这些多处来的分支和字段代表什么含义、什么时候有效什么时候无效,可随着时间的推移,记忆会慢慢消减,软件维护人员也会发生变动,这些冗余出来的“遗产”将晦涩难懂,难以维护。


对于这种情况,要求软件设计人员尽量摈弃惯性思维,脱离既有的系统实现,从需求实际出发对模型进行认识,提出符合模型本身的软件设计,避免简单地将实现套在已有的模式上。


  • 设计过程中对业务领域的新认识无法反映到模型中。


实际当中,不可能要求业务专家一次性就提出完美的业务模型,必然需要经过多次反复修改完善才能逐渐趋近于现实业务领域。因而,设计人员拿到的模型往往并不是完善的,在设计过程中,设计者可能会发现新的问题,这时需要和业务专家进行沟通确认。但有些时候,这种沟通渠道可能并不畅通,这就会导致设计过程中的新发现无法及时反映到模型当中。这时,设计者只能按照自己的理解进行设计,幸运的话可能会如实反映现实业务问题,但通常可能会偏离实际问题。


那么,怎么保证模型与设计不出现脱节呢,DDD 提出了模型驱动设计(Mode-Driven Design)的概念。模型驱动设计要求,不再将模型分析与程序设计进行分离,而是作为整体看待,模型分析的成果,既要如实反映业务领域的实际问题,也要便于程序设计落地。具体来说:


软件系统设计的各部分忠实充分地反映模型

软件可以更加自然地实现模型

模型能够支撑健壮的通用语言

Hands-On Modeler


我们已经反复强调了模型与实现保持紧密联系的重要性,实际当中遵循模型与实现绑定还需要注意“最后一公里”的问题。


当团队开始变大之后,前期的设计工作会由有经验的开发人员承担,这是理所应当的。但同时,有经验的开发人员容易脱离一线开发,因为他们忙着做“重要”的设计和解决“困难”的问题,不能“浪费时间”来实现业务需求。这种想法的基本出发点在于,认为实现业务需求在分析设计完成后仅仅是一项“搬运”性质的劳动,是程序开发届“二等公民”的职责,那些有经验的开发者应该发挥更大的价值去做更重要的事情。这里需要再次重申的是,软件开发本身就是设计,每一行代码中都包含着开发者的设计思路。


如果把设计和代码实现强行分割,容易出现“高水平设计,低水平实现”的问题,有经验的设计者抱怨自己的设计没有被如实实现,而那些真正编写代码的初级开发者并不知道他们“高深”设计所要传达的意思。在一项动态宣传页的需求中,我们需要实现一个仅通过拖拽和填写关键信息就可以实现不同内容宣传页的需求,作为设计者,我与 PO 及前端开发负责人进行反复沟通,最终形成了我所认为完善的设计,而后,我将设计交给了组内的其他人去实现,而我自己则去忙其他事情了,几天后当我们走查代码时我发现,开发人员所开发的代码并没有完全体现我所想表达的意思,一些功能甚至完全不可用。


为什么会出现这种情况呢,有几方面的原因


  • 设计意图丢失。有经验的设计者往往掌握更多的设计和程序实现知识,而这些知识可能对于初级开发人员是未知的,所以在他们实现时并不能体现最初的设计意图。

  • 问题无法得到及时反馈。在实际任务当中,我不止一次的发现不合理的实现,当我理智气壮地去质问编码人员的时候,他们会指出设计中不合理的地方,并告诉我现在的实现是他们对原有设计进行调整后得出的。这里的关键问题还是在于沟通问题,那些在设计阶段完成后去应付“其他重要事情”的设计人员往往神龙见首不见尾,编码人员只能按照自己的理解进行调整、实现。

  • 随着时间推移,设计者们会遗忘程序实现的关键细节。假设一个有五年以上经验的开发人员开始负责系统的设计并不写一行代码,半年甚至一年以后,他或多或少会忘记程序实现的那些关键细节,这些细节虽然仅仅是实现手段,但会决定设计是否能够落地。


为此,领域驱动设计提倡 Hands-On Modeler,即软件设计人员需要真正动手编写程序,甚至业务专家也要去花时间了解技术,只有保持对真实实现的最新认知,才能设计出真正可以落地的软件。当然,这并不是说那些有经验的开发人员必须事必躬亲,这显然是精力所不允许的,但至少要保证不脱离一线,对于自己的设计至少要进行关键部分的实现,经过初步验证可行之后,才移交给其他开发人员进行开发。同时,也要保持与其他开发人员的密切沟通,及时发现设计中的不合理和不完善之处进行调整。


发布于: 2021 年 03 月 27 日阅读数: 16
用户头像

luojiahu

关注

喜欢思考组织、过程、产品的后端开发 2017.01.08 加入

还未添加个人简介

评论

发布
暂无评论
领域驱动设计101 - 绑定模型与实现