当前位置: 首页 > Web前端 > HTML

不容错过!什么是领域驱动设计?为什么落地这么难?

时间:2023-03-28 15:21:14 HTML

简介领域驱动设计并不是一种新的架构设计理论。从埃里克·埃文斯提出以来,已经过去十多年了。由于微服务架构的兴起,DDD常被用来指导微服务边界的划分,重新进入软件开发大众的视野。DDD的概念和普及在国外已经比较成熟,但在国内还处于发展的初级阶段。近年来国内很多社区和企业组织对DDD的讨论和应用越来越火爆,很多架构师和开发人员都对学习和实践DDD充满了热情。而且和敏捷一样,不同的团队有不同的认知和实践水平。有些人成功了,但大多数人可能会失败。领域驱动设计(DomainDrivenDesign),简称DDD,最??早于2004年由EricEvans在《Domain-Driven Design: Tackling Complexity in the Heart of Software》一书中提出。领域驱动设计是一种用于指导软件设计的方法论,是一种解决软件复杂性的设计思维方法问题,旨在加速必须处理复杂领域的软件项目的开发。实践DDD的第一步不是如何写代码,而是首先你需要对齐你对领域驱动设计的理解。下面的系列文章将从不同的角度来探讨领域驱动设计,以帮助大家更深入地了解它,并将其应用到实际的研发工作中。谈论问题空间、解决方案空间、领域模型问题空间和解决方案空间。ProblemSpace:ProblemSpace是一系列的问题,以及企业在当前环境下面临的问题背后的需求。通常,业务和产品领域的专家会主导问题和需求的收集、描述和分析。问题空间框定了我们要解决的问题的上下文。这种上下文不是软件工程或领域驱动所独有的,而是一个共同的元素。工程实践必然发生在某些背景下。解决方案空间:SolutionSpace,解决方案空间是对问题空间的解决方案,属于工程实现阶段,由技术专家主导方案设计。软件开发过程,本质上可以看作是问题空间到解决方案空间的映射转换:问题空间,针对相关的需求场景和用例,找出业务挑战并分析解决方案空间,设计并实现域通过特定的技术工具。、模型和领域模型领域:领域“领域”是“知识或活动的集合”。与软件系统相比,领域才是软件应用真正需要解决的问题领域。一个领域对应一个问题空间,是特定范围边界内业务需求的总和。领域模型:领域模型抽象是化繁为简的能力,是人类认识世界的利器,是一种生物本能。在脑容量有限的前提下,人类不可能存储和记住所有细节,海量信息已经超出了人脑的存储极限,无法容纳和有效获取。抽象使人类能够屏蔽不相关的细节,提取高级有效信息进行记忆存储。试想一下,如果脑机接口技术有突破,人脑背后链接着大量高效的计算机集群。随着这种无限存储、计算和检索能力的增强,“抽象能力可能会被削弱”。模型用于表达人们所关心的现实或想法的某些方面,本质上是抽象过程的产物,将与解决方案密切相关的方面抽象出来,而忽略不相关的细节。专注于软件工程领域,为了构建满足需求的软件系统,开发团队需要具备非常庞大复杂的面向软件领域的知识,而模型是解决这种信息过载的有效工具问题。对领域建模的过程就是领域建模。领域建模的目的并不是要建立一个100%符合“现实”的模型。从理论上讲,我们无法实现这种对现实的完整建模,而只是对现实的一种模拟。领域建模的输出是领域模型,是特定领域内关键事物及其关系的可视化表示,属于解空间的范畴。为了准确定义需要解决的问题而构建的抽象模型,统一了对软件系统构建目标的认知,是软件系统中业务功能场景的映射和转换。领域模型不是领域专家头脑中的知识,而是对这些知识的严格组织和选择性抽象。同时,领域模型不是特殊的图表、文字或代码,而是它们所传达的思想。图表、文字或代码都可以作为模型的表示或交流形式,但它们不是模型,而是不同维度的模型视图。领域驱动设计领域驱动设计强调领域模型的重要性,通过模型驱动设计保证领域模型与程序设计的一致性。领域驱动设计首先从业务需求中提炼出统一的语言,建立领域模型来指导程序设计和编码实现;最后,通过重构发现隐含概念,不断解决领域领域模型相关的新问题。本质上,领域驱动设计也是从问题空间到解决方案空间的映射。领域驱动设计结合了宏观和微观层面的设计,分别对应于领域驱动概念中的战略设计和战术设计。领域驱动设计:战略设计战略设计的初衷是维护模型的完整性,主要从以下两个方面着手:问题领域:将问题的规模拆解,划分为不同类型的子领域,以及确定核心域和其他子域。解决方案层:划分有界上下文和上下文映射,合理分解问题域,确定上下文边界以及它们之间的关系。领域驱动设计:战术设计战略设计的初衷是为了保持模型的完整性,通过战略设计将整个软件系统分解为多个限界上下文,然后针对每个限界上下文进行战术设计。为每个限界上下文设计策略。EricEvans提供的模型驱动设计的结构元素和元素之间的关系如下图所示:Entity:实体,不同于传统的由属性定义的对象,实体对象由唯一标识符区分,具有连续的生命周期。Valueobject:ValueObject,值对象是具有属性但没有唯一标识的不可变对象。领域事件:DomainEvents,领域事件用于记录系统中与模型活动相关的离散事件。尽管系统中的所有事件都应该能够被跟踪,但只有领域专家关注的事件类型才会创建领域事件。Aggregation:聚合,聚合对象是实体和值对象的聚合,聚合有一个唯一的根,即聚合根。外部对象不再直接访问聚合内部的单个对象或实体,而是直接访问聚合根,并使用聚合根向相应的组传递指令。领域服务:DomainService,一些领域逻辑不适合赋值给具体的实体对象,这些操作可以封装到领域服务资源库:Repositories,资源库不是配置库,它提供了一个全局接口来访问特定的聚合所有内部实体类和值对象都应该包括创建、修改和删除聚合内部对象的方法。Factory:工厂,工厂封装了创建复杂对象和聚合的逻辑,屏蔽了客户端创建的复杂性,也没有遵循所有的战术设计模式,符合领域驱动设计。因为实践DDD的关键不是这个战术层面模型的实现,而是坚持其宏观领域驱动的设计思想,比如统一的语言,领域模型和代码的一致性,子领域和上下文的拆分和映射,领域模型与技术问题的分离等等。另外,随着DDD的不断发展,出现了一些新的构建模型,旧的构建模型可能已经不能满足团队研发的要求。为什么领域驱动设计这么难实现?需要强大的领域知识,依赖项目中领域专家的支持如果团队中没有熟悉应用程序所需领域知识的领域专家,即使是最熟练的开发人员也无济于事。在某些情况下,领域驱动设计需要一个或多个外部人员在整个软件开发生命周期中充当领域专家。在某些情况下,领域驱动设计需要在整个软件开发生命周期中与外部团队成员(以领域专家的角色)协作。在创新业务中应用DDD也存在挑战。由于业务模型的不确定性,业务需求的频率和范围变化很??大,同时也缺乏新领域的领域专家。整个业务处于探索模式,很难建立一个相对稳定、复用性高的领域模型。强调持续迭代和持续集成可能会给缺乏迭代经验和关注瀑布模型的团队带来障碍领域驱动设计实践依赖持续迭代和持续集成来构建高扩展性的项目,但这次基于迭代和持续集成,登陆某些团队可能是一个障碍,特别是如果过去的经验是基于诸如瀑布之类的刚性开发模型。不适合面向技术的应用领域驱动设计适用于领域复杂度非常高(复杂的业务逻辑)的应用,但不适合领域复杂度低但技术复杂度高的领域。DDD强调需要领域专家来构建项目所依赖的统一语言和领域模型,但是如果项目的技术复杂度很高,领域能否理解是一个挑战。当所有团队成员都没有完全理解技术要求或限制时,可能会导致问题团队过于关注战术设计,从而导致实践指南和原则的偏差。团队对领域驱动设计的理解不够,精力没有集中在问题领域的拆分和统一上。在语言、模型、技术关注点分离等核心原则上,从一开始就从实现的角度触发,过分强调战术设计模式的实现,从而陷入无穷无尽的技术细节作者:倪新明