领域驱动设计现存的不足(福利赠书)

简介: 领域驱动设计现存的不足(福利赠书)

只凭经验,我们得经过遥遥辽远的汗漫之游,才能得到便利直捷之径。

洛节·爱铿,转引自托马斯·哈代的《德伯家的苔丝》


距离领域驱动设计的提出已有十余年,开发人员面对的软件开发模式、开发技术和IT规模都有了天翻地覆的变化。即使领域驱动设计作为一种设计思维方式与软件设计过程,并未涉及具体的开发技术,但技术的发展仍然会对它产生影响,就连Eric Evans自己也认为:“如果在推行领域驱动设计时继续照本宣科地使用《领域驱动设计》一书,这就不太光彩了!”[①]


领域驱动设计具有一定的开放性,只要遵循“以领域为驱动力”的核心原则,就可以在软件构建过程中使用不限于领域驱动设计提出的方法,以控制软件复杂度。事实上,在领域驱动设计社区的努力下,如今的领域驱动设计包容的实践方法与模型已经超越了Eric Evans最初提出的领域驱动设计范畴。这是一套可以自我成长自我完善的过程体系,只要软件仍然以满足用户的业务需求为己任,领域驱动设计就不会脱离它成长的土壤。


既然看到了领域驱动设计的开放性,只要不违背它的核心原则,我们自然可以按照对它的理解,结合自身在项目中的实践来扩展整套方法论。社区对领域驱动设计的补充更多地体现在对设计元模型的不断丰富上。以“模式”作为表达方式的设计元模型是一种松散的组织方式,每个模式都有其意图与适用性,这意味着我们可以轻松地添加新的模式。目前,社区已经为这套设计元模型分别增加了诸如支撑子领域、领域事件、事件溯源、命令查询职责分离command queryresponsibility segregationCQRS)等模式,本书也针对上下文映射提出了发布者/订阅者模式(参见第10章),为限界上下文定义了菱形对称架构模式(参见第12章),在领域建模阶段增加了角色构造型(参见第16章)的概念,提出了服务驱动设计(参见第16章)方法。


领域驱动设计的开放性还体现在适用范围的扩大。它作为一种方法论,囊括了在软件设计领域提炼出来的诸多真知灼见,并以设计原则和模式的形式将其呈现出来。这些设计原则和模式具备技术领先性和前瞻性,体现了顽强的生命力,仿佛可以预见技术发展的未来。例如:它“预见”了微服务架构,可以将限界上下文作为设计和识别微服务边界的参考模式;它“预见”了文档型的NoSQL数据库,可以使用聚合模式封装NoSQL数据库的每一项;它“预见”了中台战略,可以通过对子领域的划分提供能力中心构建的设计支持。


领域驱动设计的开放性是其永葆青春的秘诀。当然,在选择为这套方法论添砖加瓦时,也不能率意而为,肆意扩大领域驱动设计的外延,仿佛它是一个筐,什么都能向里面装。本着实证主义的态度,在对现有领域驱动设计体系进行完善之前,需要充分了解它现存的不足。


3.1 领域驱动设计现存的不足[②]

领域驱动设计体系构建在设计元模型的基础之上,具有前所未有的开放性。然而,这种由各种模式构成的松散模型却也使得它对设计上的指导过于随意,对技能的要求过高。如果没有掌握其精髓,就难以合理地运用这些设计元模型。归根结底,领域驱动设计缺乏一个系统的统一过程作为指导。虽然领域驱动设计划分了战略设计阶段与战术设计阶段,但这两个阶段的划分仅仅是对构成元模型的模式进行类别上的划分,例如将限界上下文、上下文映射等模式划分到战略设计阶段,将聚合、实体、值对象等模式划分到战术设计阶段,却没有一个统一过程去规范这两个阶段需要执行的活动、交付的工件以及阶段里程碑,甚至没有清晰定义这两个阶段该如何衔接、它们之间执行的工作流到底是怎样的。毕竟,除了极少数精英团队,大多数开发团队都需要一个清晰的软件构建过程作为指导。领域驱动设计没能形成这样的统一过程,使得其缺乏可操作性。团队在运用领域驱动设计时,更多取决于设计者的行业知识与设计经验,使得领域驱动设计在项目上的成功存在较大的偶然性。因此,领域驱动设计缺乏规范的统一过程,是其不足之一


域驱动设计倡导以“领域”为设计的核心驱动力,这就需要针对问题空间的业务需求进行领域知识的抽象精炼


可是,系统的问题空间是如何识别和界定出来的?问题空间的业务需求又该如何获得,具备什么样的特征?如何定义它们的粒度和层次?如何规范和约定团队各个角色对问题空间的探索和分析?在不同阶段,业务需求的表现形式与验证标准分别是什么?针对种种问题,领域驱动设计都没有给出答案,甚至根本未曾提及这些内容!


虽说可以将这些问题纳入需求管理体系,从而认为它们不属于领域驱动设计的范畴,可是,不同层次的业务需求贯穿于领域驱动设计过程的每个环节,例如识别限界上下文需要对业务需求和业务流程有着清晰的理解,建立领域模型需要的领域知识和概念也都来自于细粒度层次的业务需求,更不用说领域驱动设计本身就强调领域专家需要就领域知识与开发团队进行充分沟通。可以说,没有好的问题空间分析,就不可能获得高质量的领域架构与领域模型。因此,领域驱动设计缺乏与之匹配的需求分析方法,是其不足之二


领域驱动设计战略设计阶段的核心模式是限界上下文,指导架构设计的核心模式是分层架构,前者决定了业务架构和应用架构,后者决定了技术架构。领域驱动设计的核心诉求是让业务架构和应用架构形成绑定关系,同时降低与技术架构的耦合,使得在面对需求变化时,应用架构能够适应业务架构的调整,并隔离业务复杂度与技术复杂度,满足架构的演进性。领域驱动设计虽然给出了这些模式的特征,却失之于简单松散,不足以支撑复杂软件项目的架构需求。更何况,对于如何从问题空间映射到战略层次的解空间、问题空间的业务需求如何为限界上下文与上下文映射的识别提供参考等问题,领域驱动设计完全语焉不详。因此,领域驱动设计缺乏规范化的、具有指导意义的架构体系,是其不足之三


战术设计阶段,领域驱动设计虽然以模型驱动设计为主线,却没有给出明确的领域建模方法。无论是否采用敏捷的迭代建模过程,整个建模过程分为分析、设计和实现这3个不同的活动都是客观存在的事实。虽然要保证领域模型的一致性,但这3个活动存在明显的存续关系,每个活动的目标、参与角色和建模知识存在本质差异,这也是客观存在的事实。领域驱动设计却没有为领域分析建模、领域设计建模和领域实现建模提供对应的方法指导,建模活动率性而为,要获得高质量的领域模型,主要凭借建模人员的经验。因此,领域驱动设计的领域建模方法缺乏固化的指导方法,是其不足之四


3.2 领域驱动设计统一过程

针对领域驱动设计现存的这4个不足,我对领域驱动设计体系进行了精简与丰富。精简,意味着做减法,就是要剔除设计元模型中不太重要的模式,凸显核心模式的重要性,并对领域驱动设计过程进行固化,提供简单有效的实践方法,建立具有目的性和可操作性的构建过程;丰富,意味着做加法,就是突破领域驱动设计的范畴,扩大领域驱动设计的外延,引入更多与之相关的方法与模式来丰富它,弥补其自身的不足。


软件构建的过程就是不断对问题空间求解获得解决方案,进而组成完整的解空间的过程。在这个过程中,若要构建出优良的软件系统,就需要不断控制软件的复杂度。因此,我对领域驱动设计的完善,就是在问题空间与解空间背景下,定义能够控制软件复杂度的领域驱动设计过程,并将该过程执行的工作流限定在领域关注点的边界之内,避免该过程的扩大化。我将这一过程称为领域驱动设计统一过程domain-driven design unified processDDDUP)。


未完待续



[①]   来自 Eric Evans 2017年的Explore DDD 大会上所作的开幕式主题演讲。

[②]   这里分析的不足,主要针对Eric Evans的著作《领域驱动设计》中的内容,社区针对这些不足也提出了各自的解决方案或模式。


本文摘录于张逸老师新书《解构领域驱动设计》。

相关文章
|
6月前
|
存储 安全 编译器
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计(下)
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计(下)
|
2月前
|
存储 Web App开发 运维
发布、部署,傻傻分不清楚?从概念到实际场景,再到工具应用,一篇文章让你彻底搞清楚
部署和发布是软件工程中经常互换使用的两个术语,甚至感觉是等价的。然而,它们是不同的! • 部署是将软件从一个受控环境转移到另一个受控环境,它的目的是将软件从开发状态转化为生产状态,使得软件可以为用户提供服务。 • 发布是将软件推向用户的过程,应用程序需要多次更新、安全补丁和代码更改,跨平台和环境部署需要对版本进行适当的管理,有一定的计划性和管控因素。
150 1
|
6月前
|
安全 Java C++
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计(上)
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计
|
7月前
|
前端开发 JavaScript Java
|
11月前
|
存储 前端开发 数据可视化
【领域驱动设计】三分钟搞懂领域驱动设计(二)
【领域驱动设计】三分钟搞懂领域驱动设计
|
11月前
|
存储 开发框架 Java
【领域驱动设计】三分钟搞懂领域驱动设计(一)
【领域驱动设计】三分钟搞懂领域驱动设计
|
11月前
|
存储 前端开发 数据可视化
【领域驱动设计】三分钟搞懂领域驱动设计(下)
【领域驱动设计】三分钟搞懂领域驱动设计
|
11月前
|
存储 开发框架 Java
【领域驱动设计】三分钟搞懂领域驱动设计(上)
【领域驱动设计】三分钟搞懂领域驱动设计
|
11月前
|
存储 前端开发 数据可视化
【领域驱动设计】大神三分钟搞懂领域驱动设计(下)
【领域驱动设计】大神三分钟搞懂领域驱动设计
|
11月前
|
存储 开发框架 Java
【领域驱动设计】大神三分钟搞懂领域驱动设计(上)
【领域驱动设计】大神三分钟搞懂领域驱动设计