域驱动设计是程序员Eric Evans在2004年的著作《域驱动设计:解决软件中心的复杂性》中提出的概念。
通过以自上而下的方式查看软件,这是一种用于设计软件设计的方法。在详细讨论主题之前,让我们尝试重点介绍一下在这种情况下领域的含义。
什么是域名?
在软件开发的上下文中使用的“域”一词是指业务。在应用程序开发过程中,通常使用术语域逻辑或业务逻辑。基本上,业务逻辑是应用程序逻辑所围绕的知识领域。应用程序的业务逻辑是一组规则和准则,用于解释业务对象应如何相互交互以处理建模数据。
笔记 –
软件工程领域的领域是要在其上构建应用程序的业务。
域驱动设计:
假设我们已经使用所有最新的技术堆栈和基础架构设计了软件,并且我们的软件设计体系结构很棒,但是当我们在市场上发布该软件时,最终用户将决定我们的系统是否出色。同样,如果系统不能解决业务需求,对任何人都没有用。无论外观多么漂亮,或其基础架构的结构如何。根据埃里克·埃文斯(Eric Evans)的说法,在开发软件时,我们的重点不应主要集中在技术上,而应主要集中在业务上。记住,
It is not the customer’s job to know what they want” – Steve Jobs
领域驱动的设计讨论两种设计工具,第一种是战略设计工具,另一种是战术设计工具。程序员或开发人员通常使用战术设计工具,但是如果我们对战略设计工具有足够的了解和理解,那么它将有助于我们设计好的软件。
Spring数据系列下的大多数框架都是在考虑域驱动设计方法的情况下构建的。
战略设计:
战略设计工具可帮助我们解决与软件建模有关的所有问题。这是一种类似于面向对象设计的设计方法,在这种设计方法中,我们被迫根据对象进行思考。在进行战略设计时,我们被迫根据上下文进行思考。
语境 :
我们可以认为这是一个英文单词,指的是事件,事件,陈述或想法的情况,可以确定其含义。
除了上下文,战略设计还讨论模型,泛在语言和有限上下文。这些是域驱动设计的战略设计中使用的通用术语。让我们一一理解。
- 模型 –
它充当核心逻辑并描述领域的选定方面。它用于解决与该业务有关的问题。 - 无处不在的语言–
所有团队成员使用的通用语言来连接团队围绕领域模型的所有活动。与领域专家和团队成员交谈时,可以将其视为对类,方法,服务和对象使用通用动词和名词。 - 有限的上下文–
它是指上下文的边界条件。它是对边界的描述,并充当阈值,在其中定义并应用了特定的领域模型。
战术设计:
战术设计讨论实现细节,即建模领域。它通常会处理有界上下文中的组件。我们可能听说过或使用过诸如服务,实体,存储库和工厂之类的东西。它们都是通过域驱动设计创造并流行的。战术设计过程发生在产品开发阶段。
让我们讨论一些重要的战术设计工具。这些工具是可用于创建和修改域模型的高级概念。
- 实体 –
致力于面向对象原理的程序员可能知道称为类和对象的概念。在这里,实体是具有某些属性的类。这些类的实例具有全局标识,并且在整个生命周期中都保持相同的标识。请记住,财产状态可能会发生变化,但身份永远不会改变。简而言之,实体可以实现一些业务逻辑,并且可以使用ID进行唯一标识。在编程的上下文中,它通常在DB中作为行持久保存,并且由值对象组成。 - 价值对象–
这些是不可变的轻量级对象,没有任何标识。价值对象通过执行复杂的计算,将繁重的计算逻辑与实体隔离开来,从而降低了复杂性。在上图中,用户是一个实体,地址是一个值对象,地址可以更改很多次,但用户的身份永远不会更改。每当地址更改时,都会实例化一个新地址并将其分配给用户。
- 服务 –
服务是无状态的类,可以适合实体或值对象以外的其他地方。简而言之,服务是一种功能,存在于实体和值对象之间的某个位置,但它既不与实体相关,也不与值对象相关。 - 骨料–
当我们有更大的项目时,对象图变大,而对象图越大,维护它就越困难。集合是在单个交易边界内的实体和值的集合。基本上,聚合可以控制更改,并且具有一个称为聚合根的根实体。根实体控制聚合中其他实体的生命周期。在上面的示例中,如果删除了根实体User或Order ,则与该根实体关联的其他实体将无用,并且此关联信息也将被删除。这意味着聚合在本质上始终是一致的,这是在域事件的帮助下完成的。生成域事件以确保最终的一致性。
在上面的示例中,如果用户的地址已更改,则它也必须反映在“订单”中。为此,我们可以从用户到订单触发一个域事件,以便处理订单更新的地址,从而使我们最终具有一致性,并且最终使订单保持一致。聚合和聚合根的其他示例可以是帖子评论,问答详细信息,银行交易详细信息等。像hibernate这样的ORM工具在创建一对多或多对多关系时会大量使用聚合。
- 工厂和存储库–
工厂和存储库用于处理聚合。工厂有助于管理聚合生命周期的开始,而存储库则有助于管理聚合生命周期的中期和结束。工厂有助于创建聚合,而存储库则有助于持久聚合。我们应该始终为每个聚合根创建一个存储库,而不是为所有实体创建一个存储库。
工厂是GoF的设计模式,工厂是有用的,但在汇总规则的上下文中不是强制性的。
域驱动设计的优点:
- 它提高了我们的工艺水平。
- 它提供了灵活性
- 与接口相比,它更喜欢域
- 通过无处不在的语言减少团队之间的沟通差距
域驱动设计的缺点:
- 它需要具有丰富领域专业知识的专业人员
- 它鼓励团队遵循迭代实践