`

【转】聚合根、实体、值对象的区别?

阅读更多

1.      聚合根、实体、值对象的区别?

从标识的角度:

聚合根具有全局的唯一标识,而实体只有在聚合内部有唯一的本地标识,值对象没有唯一标识,不存在这个值对象或那个值对象的说法;

从是否只读的角度:

聚合根除了唯一标识外,其他所有状态信息都理论上可变;实体是可变的;值对象是只读的;

从生命周期的角度:

聚合根有独立的生命周期,实体的生命周期从属于其所属的聚合,实体完全由其所属的聚合根负责管理维护;值对象无生命周期可言,因为只是一个值;

2.  聚合根、实体、值对象对象之间如何建立关联?

聚合根到聚合根:通过ID关联;

聚合根到其内部的实体,直接对象引用;

聚合根到值对象,直接对象引用;

实体对其他对象的引用规则:1)能引用其所属聚合内的聚合根、实体、值对象;2)能引用外部聚合根,但推荐以ID的方式关联,另外也可以关联某个外部聚合内的实体,但必须是ID关联,否则就出现同一个实体的引用被两个聚合根持有,这是不允许的,一个实体的引用只能被其所属的聚合根持有;

值对象对其他对象的引用规则:只需确保值对象是只读的即可,推荐值对象的所有属性都尽量是值对象;

3. 如何识别聚合与聚合根?

明确含义:一个Bounded Context(界定的上下文)可能包含多个聚合,每个聚合都有一个根实体,叫做聚合根;

识别顺序:先找出哪些实体可能是聚合根,再逐个分析每个聚合根的边界,即该聚合根应该聚合哪些实体或值对象;最后再划分Bounded Context;

聚合边界确定法则:根据不变性约束规则(Invariant)。不变性规则有两类:1)聚合边界内必须具有哪些信息,如果没有这些信息就不能称为一个有效的聚合;2)聚合内的某些对象的状态必须满足某个业务规则;

 

例子分析1:订单模型

Order(一 个订单)必须有对应的客户信息,否则就不能称为一个有效的Order;同理,Order对OrderLineItem有不变性约束,Order也必须至少有一个OrderLineItem(一条订单明细),否 则就不能称为一个有效的Order;另外,Order中的任何OrderLineItem的数量都不能为0,否则认为该OrderLineItem是无效 的,同时可以推理出Order也可能是无效的。因为如果允许一个OrderLineItem的数量为0的话,就意味着可能会出现所有 OrderLineItem的数量都为0,这就导致整个Order的总价为0,这是没有任何意义的,是不允许的,从而导致Order无效;所以,必须要求 Order中所有的OrderLineItem的数量都不能为0;那么现在可以确定的是Order必须包含一些OrderLineItem,那么应该是通 过引用的方式还是ID关联的方式来表达这种包含关系呢?这就需要引出另外一个问题,那就是先要分析出是OrderLineItem是否是一个独立的聚合 根。回答了这个问题,那么根据上面的规则就知道应该用对象引用还是用ID关联了。那么OrderLineItem是否是一个独立的聚合根呢?因为聚合根意 味着是某个聚合的根,而聚合有代表着某个上下文边界,而一个上下文边界又代表着某个独立的业务场景,这个业务场景操作的唯一对象总是该上下文边界内的聚合 根。想到这里,我们就可以想想,有没有什么场景是会绕开订单直接对某个订单明细进行操作的。也就是在这种情况下,我们 是以OrderLineItem为主体,完全是在面向OrderLineItem在做业务操作。有这种业务场景吗?没有,我们对 OrderLineItem的所有的操作都是以Order为出发点,我们总是会面向整个Order在做业务操作,比如向Order中增加明细,修改 Order的某个明细对应的商品的购买数量,从Order中移除某个明细,等等类似操作,我们从来不会从OrderlineItem为出发点去执行一些业 务操作;另外,从生命周期的角度去理解,那么OrderLineItem离开Order没有任何存在的意义,也就是说OrderLineItem的生命周 期是从属于Order的。所以,我们可以很确信的回答,OrderLineItem是一个实体。

 

例子分析2:帖子与回复的模型,做个对比,以便更好地理解。

不 变性分析:帖子和回复之间有不变性规则吗?似乎我们只知道一点是肯定的,那就是帖子和回复之间的关系,1:N的关系;除了这个之外,我们看不到任何其他的 不变性规则。那么这个1:N的对象关系是一种不变性规则吗?不是!首先,一个帖子可以没有任何回复,帖子也不对它的回复有任何规则约束,它甚至都不知道自 己有多少个回复;再次,发表了一个回复和帖子也没有任何关系;其次,发表回复对帖子没有任何改变;从业务场景的角度去分析,我们有发表帖子的场景,有发表 回复的场景。当在发表回复的时候,是以回复为主体的,帖子只是这个回复里所包含的必要信息,用于说明这个回复是对哪个帖子的回复。这些都说明帖子和回复之 间找不出任何不变性约束的规则;因为帖子和回复都有各自独立的业务场景的需要,所以可以很容易理解它们都是独立的聚合根;那也很容易知道该如何建立他们之 间的关联了,但是我们要尽量减少关联,所以只保留回复对帖子的关联即可;帖子没有任何必要去保存一个回复的ID的列表;那么你可能会说,当我删除一个帖子 后,回复应该是没有存在的意义的呀?不对,不是没有存在的意义,而是删除了帖子后导致了回复对帖子的关联信息的缺失,导致数据不一致。这是因为帖子和回复 之间有一种必然的联系(1:N),回复一定会有一个对应的帖子;但是回复有其自己的生命周期,不应该随着帖子的删除而级联删除。这种情况下,如果你删除了 帖子,就导致回复也成为了一条无效的数据;所以,我们绝对不允许删除任何聚合根,因为一旦你删除了聚合根,那就意味着与该聚合根相关的其他任何聚合根都会 有外键引用缺失的问题,会导致整个领域模型数据的不一致;所以,永远都不要删除聚合根;

分享到:
评论

相关推荐

    DDD战术设计的目的是使得业务能够从技术中分离并突显出来,让代码直接表达业务的本身,其中包含了聚合根、应用服务、资源库、工厂等概

    **聚合根**是领域模型中的一个关键组件,它是一种特殊的实体,负责管理聚合内部的实体和值对象,确保聚合的完整性。聚合是一组具有强一致性边界的对象,任何对聚合的修改都必须在一次事务中完成,以保持数据的一致性...

    大白话领域驱动设计DDD视频教程

    实体和值对象? 贫血模型的优缺点? DDD提倡的充血模型是什么? 体会下充血模型开发微信钱包系统 聚合和聚合根是什么? 领域事件是什么? 看看领域事件的本质(解耦,异步,削峰) 工厂和资源库的作用? 领域服务是...

    DDD领域驱动设计初探(1):聚合 - 文章 - 伯乐在线1

    域模型,包含实体、值对象、领域服务、领域事件等,是业务逻辑的核心。领域层应当尽可能保持独立,不依赖于任何基础设施或技术细节。领域层的代码应该由领域专家和开发人员共同编写,确保遵循业务规则。 领域模型:...

    领域驱动聚合设计工作坊

    在对象关系中,聚合通常由实体和值对象组成,其中实体具有唯一标识,而值对象只关注其属性值。 聚合的设计需要遵循以下原则: 1. **概念完整性**:确保聚合内的对象共享相同的业务语义和规则,形成一个完整的概念。...

    DDD领域设计模式代码案例

    2. **聚合**:聚合是DDD中的一个关键概念,它是一组相关对象的集合,有一个根元素,即聚合根,其他对象被称为聚合内的实体或值对象。聚合保持其内部的一致性,对外界提供统一的访问接口。例如,在订单管理中,订单是...

    转转定价平台DDD实践共21页.pdf.zip

    聚合根是聚合中的主对象,负责整个聚合的边界和完整性。 4. **实体(Entity)**:具有唯一标识的业务对象,其身份在业务规则中起关键作用。 5. **值对象(Value Object)**:关注于某个属性的集合,不关心其身份,...

    领域模型代码示例

    3. 聚合:聚合是一组相关实体和值对象的集合,其中有一个主实体称为聚合根。聚合是事务处理和一致性边界,所有修改都应该在一个聚合内部完成。例如,订单是一个聚合,包含订单项这样的子实体,而订单本身是聚合根。 ...

    一个超级简单的DDD领域架构,大致流程步骤有注释

    2. **聚合根**:聚合是DDD中的一个基本单元,它由一个主实体(聚合根)和一些相关联的实体或值对象组成。聚合根是聚合的入口点,负责维护内部的业务规则一致性。例如,可能有一个`Order`作为聚合根,管理订单相关的...

    领域驱动设计中实体与限界上下文的重构方法

    内容涵盖如何从数据库表转换成Java类、属性与方法的定义、实体、值对象、聚合根和服务的概念,以及在限界上下文中封装类元素以避免不必要的副作用。同时讨论了关系管理、通用语言的创建与维护,以及验证过程。 适用...

    Laravel开发-core-domain

    聚合根是实体的一种特殊形式,是领域模型中的一组相关实体和值对象的入口点。所有对聚合内的修改都必须通过聚合根进行。 5. **领域服务(Domain Services)** 当某些操作不适合放在实体或值对象中时,可以创建...

    基于DDD的Java开发模板.zip

    在DDD中,核心概念包括领域模型(Domain Model)、聚合(Aggregate)、实体(Entity)、值对象(Value Object)、领域事件(Domain Event)和服务(Service)。这些概念帮助我们更好地理解和组织业务逻辑。 1. 领域...

    Laravel开发-laravel-5.2-ddd

    主要概念包括:聚合根、实体、值对象、领域事件、仓储和工厂等。在 Laravel 中,我们可以利用 Eloquent ORM 来构建领域模型,使用事件监听器来处理领域事件,通过服务提供者来注册领域服务。 3. **聚合根** 聚合根...

    DDD Reference 最新版本Eric Evan-领域驱动设计

    1. **领域模型**:领域模型是DDD的核心,它是一个抽象的、以业务规则为中心的模型,用来表示领域中的实体、值对象、聚合根、领域事件等概念。例如,一个银行系统可能有账户、交易和余额等实体,它们之间的关系和操作...

    【精品】领域驱动DDD聚合工作坊19.9.pdf

    2. 确定对象是实体(Entity)还是值对象(Value Object)。实体具有唯一标识,而值对象关注的是属性值。 3. 把具有继承或合成关系的对象放入同一个聚合边界内,以保持概念的完整性。 4. 梳理聚合的本质,确保每个...

    领域模型1

    领域模型包含了业务实体、值对象、聚合根、领域事件、服务、工厂、仓储等核心元素。 1. **业务实体**:业务实体是领域模型中的核心,代表了业务中的重要对象,如用户、订单、产品等。它们有自己的标识,并且可以...

    .NET Domain-driven design with C# 源码 chapter 2

    在C#中,通常通过类来表示领域模型,这些类封装了业务行为和状态,如实体(Entity)、值对象(Value Object)、聚合根(Aggregate Root)等。 2. **实体(Entity)**:实体是具有唯一标识的对象,标识符通常是不可...

    DDD领域驱动设计大会演讲ppt(5/5)

    聚合是领域模型中的一个关键组件,它是一组相关的实体和值对象的集合,其中包含一个根实体,即聚合根。聚合根负责维护聚合的完整性和一致性,对外提供统一的接口进行交互。 **分布式系统与DDD** 在分布式系统中,...

    《领域驱动设计C# 2008实现问题.设计.解决方案》.((美)Tim McCarthy) [PDF].rar

    2. **实体与值对象**:实体具有唯一标识,如用户ID;值对象关注属性集合的整体,如地址。在C#中,可以使用`class`定义实体和值对象,通过接口或特性来实现业务规则的约束。 3. **聚合与聚合根**:聚合是一组相关的...

    《领域驱动设计C# 2008实现问题.设计.解决方案》.((美)Tim McCarthy) [PDF].rar_0517

    1. 领域模型:领域模型是DDD的核心,它由业务实体、值对象、聚合根、领域事件等构成,用于捕获业务领域的核心规则和行为。例如,书中可能会讲解如何创建表示业务实体的类,以及如何定义这些类的行为。 2. Bounded ...

    领域建模和架构说明

    在领域建模的过程中,我们通常会识别出不同的领域概念,如核心域、子域、边界上下文等,并定义出相应的领域对象,如值对象、实体和聚合根等。 - **核心域**:指的是当前业务场景中最核心的部分,通常包含了业务中最...

Global site tag (gtag.js) - Google Analytics