乐趣区

关于react.js:不容错过什么是领域驱动设计为什么落地这么难

引言

畛域驱动设计并不是新的架构设计实践,从 Eric Evans 提出至今曾经有十多年历史。因为微服务架构的衰亡,DDD 罕用于领导微服务边界划分,并从新宽泛进入软件研发公众的视线。DDD 的理念及利用遍及在国外绝对成熟,在国内尚处于初期倒退阶段。国内的很多社区以及企业组织外部近几年对于 DDD 的探讨和利用逐步炽热,许多架构师以及开发人员对 DDD 充斥了学习和实际的激情。而像麻利一样,不同团队对其认知程度和实际程度不尽相同,有的胜利,大多数可能是失败的。

畛域驱动设计(Domain Driven Design),简称 DDD,Eric Evans 2004 年的《Domain-Driven Design: Tackling Complexity in the Heart of Software》一书中第一次提出。畛域驱动设计 是一种用于领导软件设计的方法论,也是一种设计思维形式,用于解决软件复杂性问题,旨在减速那些必须解决简单畛域的软件我的项目的开发。

实际 DDD 的第一步不在于如何编写代码,而首先须要拉齐对畛域驱动设计的认知。后续的系列文章将围绕畛域驱动设计进行不同视角探讨,以期帮忙大家对其有更深刻的意识,并能利用的理论的研发工作中。

聊聊问题空间、解空间、畛域模型

问题空间和解决方案空间

问题空间:Problem Space,是以后环境下业务所面临的一系列问题和问题背地的需要,通常是业务和产品领域专家主导问题、需要的收集形容和剖析。问题空间框定了咱们要解决的问题的上下文,这种上下文环境不是软件工程或是畛域驱动所独有的,而是通用的共性的元素。工程实际必然处于某种上下文环境之下。

解决方案空间:Solution Space,解决方案空间是针对问题空间的解决方案,属于工程实现阶段,由技术专家主导方案设计。

软件开发过程,实质上能够看作是问题空间到解决方案空间的一个映射转化:问题空间,找出业务挑战及其对相干需要场景用例剖析解空间,通过具体的技术工具伎俩来进行设计实现

畛域、模型和畛域模型

畛域:Domain

“畛域”是“常识或流动的汇合”,绝对于软件系统而言,畛域就是软件应用所要解决的事实问题区域。畛域对应于问题空间,是一个特定范畴边界内的业务需要的总和。

畛域模型:Domain Model

形象是一种化繁为简的能力,是人类意识世界的利器,也是一种生物本能。在无限的脑容量的前提下,人类不可能存储记忆所有的细节,海量信息曾经超出人脑存储限度而无奈包容和无效获取。形象使得人类能够屏蔽无关细节信息,抽取高层的无效信息进行记忆存储。试想,如果脑机接口技术有所突破,在人脑背地链接的是海量的高效的计算机集群,这种有限的存储、计算和检索能力的加强,“形象能力兴许会被弱化”。

模型被用来表述人们所关注的事实或想法的某个方面,实质上是一种形象过程的产物,把与解决方案密切相关的方面形象进去,而疏忽无关细节。

聚焦在软件工程畛域,要想构建满足需要的软件系统,开发团队须要软件面向的畛域所波及的常识可能十分宏大和简单,而模型正是解决这种信息超载问题的无效工具。

对畛域进行模型设计的过程就是领域建模,领域建模的目标并非是要建设一个百分之百合乎“事实”的模型,实践上,咱们也无奈实现这种对事实的齐全建模,而只能是对事实某种程度的模仿。

领域建模的输入即畛域模型,畛域模型是针对特定畛域里的要害事物及其关系的可视化体现,属于解决方案空间领域。为了精确定义须要解决问题而结构的形象模型,为软件系统的构建指标对立认知,是业务性能场景在软件系统里的映射转化。畛域模型并非领域专家头脑中的常识,而是对这些常识进行严格的组织和有抉择的形象。

同时,畛域模型并非某种非凡的图、文字或者代码,而是他们所传播的思维,图、文字或代码都能够作为模型的示意或传播模式,但他们不是模型,而是不同维度的模型视图。

畛域驱动设计

畛域驱动设计强调畛域模型的重要性,并通过模型驱动设计来保障畛域模型与程序设计的统一。畛域驱动设计首先从业务需要中提炼出对立语言,并建设畛域模型领导着程序设计以及编码实现;最初,又通过重构来发现隐式概念,并一直解决畛域畛域模型相干的新问题。实质上,畛域驱动设计也是从问题空间映射到解决方案空间。

畛域驱动设计联合了宏观和宏观两个层面的设计,别离对应于畛域驱动概念中的策略设计和战术设计。

畛域驱动设计:策略设计

策略设计的初衷是要放弃模型的完整性,次要从上面两个方面来考量的:

问题域方面:将问题规模进行拆解,划分为不同类型的子域,辨认出外围畛域与其余子畛域。
解决方案层面:划分限界上下文和上下文映射对问题域进行正当的合成,确定上下文边界以及它们之间的关系。

畛域驱动设计:战术设计

策略设计的初衷是要放弃模型的完整性,通过策略设计将整个软件系统合成为多个限界上下文,而后对每个界线上下文进行战术设计。对每个限界上下文进行战术设计。Eric Evans 提供的模型驱动设计的结构因素以及因素间的关系如下图所示:

  • 实体:Entity,不同于通过属性进行定义的传统对象,实体对象通过惟一标识进行辨别,且具备继续的生命周期。
  • 值对象:Value Object,值对象是具备属性且不可变的对象,但没有惟一标识。
    畛域事件:Domain Event,畛域事件用于记录零碎内的模型流动相干的离散事件,尽管零碎内所有事件都应该可能被跟踪,但只有被领域专家关怀的事件类型才创立畛域事件。
  • 聚合:Aggregate,聚合对象是实体和值对象的聚合,聚合具备一个惟一的根,即聚合根。内部对象不再间接拜访聚合外部的单个对象或者实体,而是间接拜访聚合根,并应用聚合根将指令传递给对应的分组。
  • 畛域服务:Domain Service,某些畛域逻辑不适宜调配给某个特定的实体对象,可将其这些操作封装成畛域服务
  • 资源库:Repositories,资源库不是配置库,它提供一个全局接口来拜访特定聚合外部所有的实体类和值对象,应该包含创立,批改,删除聚合外部对象的办法。
  • 工厂:Factories,工厂封装了创立简单对象和聚合的逻辑,对客户端屏蔽创立的复杂性

上述 DDD 战术设计的模式标识了进行设计时的一些要害模式,但并非说是肯定要严格应用和遵循的,也不是遵循了所有的战术设计模式就是合乎畛域驱动设计。因为,实际 DDD 要害不在于这种战术层面模式的落地,而是在于其宏观的畛域驱动设计思维的遵循,比方对立语言、畛域模型与代码间的统一、子域及上下文的拆分以及映射、畛域模型与技术关注点的拆散等等。另外,随着 DDD 的一直倒退,一些新的构建模式曾经涌现,老的结构模型不肯定能合乎团队研发的要求。

畛域驱动设计为什么落地这么难?

  1. 须要鲁棒的畛域常识,依附我的项目中领域专家的反对
  • 如果团队中没有相熟利用所需畛域常识的领域专家,即便具备技术再强的开发人员也杯水车薪。在某些情景下,畛域驱动设计须要一个或多个内部人员在整个软件开发生命周期中表演领域专家的角色。有些状况下,畛域驱动设计须要在整个软件开发生命周期中与内部团队成员 (充当领域专家角色) 进行合作。
  • 在创新型业务中利用 DDD 同样存在挑战,因为业务模式的不确定性,业务需要变动的频率和幅度很大,同样也不足新畛域的领域专家,整个业务都处于一种摸索模式,很难建设起绝对稳固、高可复用的畛域模型。
  1. 强调一直迭代和继续集成,对不足迭代教训而偏重于瀑布模型的团队可能导致阻碍

畛域驱动设计实际依赖一直迭代和继续集成来构建高可扩大的我的项目,然而这种基于迭代和继续集成的工夫,在某些团队中落地可能会存在妨碍,特地是如果过来教训是建设在僵化的开发模型上,比方瀑布模型。

  1. 不适宜偏差技术型的利用

畛域驱动设计适宜于具备十分高畛域复杂性 (业务逻辑简单) 的利用,但不适用于畛域复杂性很低但技术复杂性很高的畛域。DDD 着重强调须要领域专家以便结构出我的项目依赖的对立语言和畛域模型,然而如果我的项目的技术复杂性很高,畛域是否了解是一种挑战。当整体团队成员没有齐全了解技术需要或限度时可能会导致问题

  1. 团队过于器重战术设计,导致实际准线和准则的偏离

团队对畛域驱动设计的认知不够,精力没有聚焦在问题域拆分、对立语言、模型与技术关注点拆散等外围原则上,而是一开始便从实现的角度触发,适度强调战术设计模式的落地,从而陷入无尽的技术细节之中

作者:倪新明

退出移动版