`

DDD 记录 实体&值对象&服务

    博客分类:
  • DDD
 
阅读更多
至少有3种方法可以使得关联更易于控制:
1. 指定一个导航的方向。
2. 通过加入限定符来有效地减少关联的多重性。
3. 清除不必要的关联。

例如:
美国和其他国家一样有过许多位总统,这就是一个双向的一对多的关联。但是,我们很少会提及乔治华盛顿这个名字时,问“他是哪个国家的总统”。所以我们就可以讲这种双向关联简化为一个单向关联。

经过深入的理解后往往可以得到一个“限定的”关系。我们会发现一个国家在一个时期只会有一个总统。这个限定条件将一对多关联简化为一对一关联,并且作为一条明确的重要规则包含在模型中,如 美国1790年时的总统是谁?乔治华盛顿。

对一个多对多关联的导航方向进行约束,会将它有效地简化为一对多这样更简单的设计。

不是在所有的业务活动中都可以这样简化。但是,无论什么特定的规则,只要发现了对象间关联的约束,就应该将它包含到模型和实现中来。这些约束使模型更加精确,也使实现更易于维护。


实体建模

当对一个对象进行建模时,我们会很自然地想到它的相关属性,对其行为的考察也非常重要。但是实体最基本的职责是保证连续性,以便使之具有清晰、可预见的行为。要更有效地实现这个目的,我们必须保持实体的精简性。对于实体而言,我们关注的重点不是它们的属性或行为,而应该把繁枝茂叶从定义中剔除出去,只留下那些固有的特性,特别是那些用来唯一标识对象,以及经常用来查找和匹配对象的特征。只加入核心概念所涉及到的行为,以及行为需要的属性。此外,想办法将属性和行为转移到与核心实体想联系的其他对象中去。这些对象可能是其他实体,也可能是值对象。

customerID是Customer实体的标识,也是其唯一的标识。但是电话号码和地址都经常被用来查找或匹配客户(所以目前先将这些属性放入Customer里面)。这种选择将取决于领域中的对象是怎样匹配和区分的。例如,如果客户有多个联系电话,那么电话号码就不具备唯一性,因此应该把它放在Sales Contact中。


值对象

如果一个对象代表了领域的某种描述性特征,并且没有概念性的标识,我们就称之为值对象。值对象就是那些在设计中我们只关心它们是什么,而不关心它们谁是谁的对象。

一个值对象可以是其他对象的集合。如窗户是由其他值对象组成的复杂的值对象。

值对象甚至可以引用实体。例如,假设我申请了一个地图服务,这里面有一个路线Route对象,它其中就包含了几个对象实体(城市和城市之间的高速公路)。

值对象通常作为参数在对象之间交换信息。他们通常是临时对象,在一个操作中创建了之后马上被丢弃了。值对象经常作为实体的属性和其他值。一个人可以被建模成一个实体,但是人的名字时一个值。

如果我们只关心模型中一个元素的属性,那么就把这个元素划分为值对象。用它来描述它所要表达的那些属性的意义,并提供相应的功能。把值对象看成是不可变的。不要给它任何标识,这样可以避免实体的维护工作,降低设计的复杂性。

例如,组成值对象的属性应该形成一个总体概念。例如,街道、城市和邮政编码不应该从Person对象中分离出去。但它们都是独立整体的一部分,这样可以使Person对象得到简化,同时也使得地址成为一个更加紧凑的值对象。

为了安全地共享对象,值对象必须具有不变性:它不能改变,除非把它整个替换掉。

复制和共享哪个开销低一些呢?这取决于实现环境。虽然复制会产生大量对象而阻塞系统,但是在分布式系统中进行共享会降低性能。

为了能够尽量利用共享带来的好吃,同时避免它的缺陷,只在以下情况中使用共享:
1. 当数据库中的存储空间和对象数量有严格限定时。
2. 当通信开销不高时(例如在一个中心服务器上)。
3. 当共享对象具有严格的不变性时。

在一些情况下考虑到系统性能,可能会允许值对象的改变。下面这些因素将倾向于在实现中允许更改:
1. 如果值经常被更改。
2. 如果对象的生成和删除的开销很大。
3. 如果替换(不是修改)会打破集群
4. 如果值没有太多的共享,或看共享没有提高集群,又或者一些其他技术方面的原因。

如果值的实现是允许更改的,那么它就不能被共享。不管您是否将值共享,都应该尽量将值对象设计成不可更改的。

服务

所谓服务,它强调与其他对象的联系。不像实体和值对象,服务完全是根据能够为客户做什么来定义的。服务往往代表一种行为,而不是一个实体,是一个动词而不是一个名词。服务可以有一个抽象的、有意图的定义,这与一个对象的定义有所不同。服务应该还有一个定义好的职责,它的职责和接口被定义为领域模型的一部分。操作名应该来自通用语言,如果通用语言中还没有这个操作名,则应该把它添加进去。调用的参数和返回的结果应该是领域对象。

一个优秀的服务具备3种特征:
1. 与领域概念相关的操作不是实体和值对象中固有的部分
2. 接口根据领域模型中的其他元素来定义。
3. 操作是无状态的。

分享到:
评论

相关推荐

    单纯的DDD代码

    1. **领域模型(Domain Model)**:这是DDD的核心,它由领域对象(如实体、值对象、聚合根等)组成,用来表示业务规则和业务状态。例如,一个电子商务项目中的订单、商品、用户都可以视为领域模型的一部分。 2. **...

    DDD领域驱动设计学习框架简介PPT

    领域服务封装了跨越多个实体或值对象的业务逻辑,而领域事件则是对业务行为的响应,通过发布事件,可以解耦组件之间的依赖,实现异步处理和状态的同步。 事件风暴是一种DDD的实践方法,它是一种集体构思活动,让...

    领域驱动模型(DDD).zip_ddd_领域模型_领域驱动_领域驱动设计

    "领域模型"则是对这个领域的抽象表示,它包含了业务规则、业务实体、值对象、聚合、领域事件等关键元素。领域模型不仅仅是数据结构,更是业务行为的载体,它能够表达领域专家的思维,并在代码中实现这些业务规则。 ...

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

    8. **战术设计**:涉及实体、值对象、工厂、仓储、领域服务等设计模式,是实现领域模型的具体技术手段。 Eric Evan的《领域驱动设计》是理解和实践DDD的重要资源。2015年的更新版可能涵盖了DDD在现代软件开发中的...

    DDD领域驱动设计相关概念

    实体对象通常包含业务规则,并且可以通过其标识与其他实体区分。 4. **值对象**:值对象不关注身份,而是关注其属性的值。例如,地址就是一个典型的值对象,两个地址如果完全相同,就可以认为它们是相同的值对象。 ...

    DDD领域驱动设计-Nop简易原型

    5. 聚合:聚合是一组相关的对象,由根实体(Aggregate Root)和值对象组成,是业务逻辑操作的最小单位。例如,Order是聚合根,包含了OrderItems、ShippingAddress等值对象。 6. 工厂模式:DDD中经常使用工厂模式来...

    DDD jDon源码

    3. **领域服务**:在jDon中,领域服务负责协调领域模型之间的交互,处理跨多个实体或值对象的操作。源码中,你可以看到领域服务类如何封装了复杂的业务流程,保持模型的纯洁性。 4. **应用服务**:作为与用户交互的...

    DDD 实践-消息系统.zip

    领域是业务的核心,由各种实体、值对象、聚合、领域事件等组成。实体具有唯一标识,值对象关注数据完整性。聚合是一组相关对象的集合,有其内部一致性规则。领域事件则记录了领域内发生的有意义变化,用于解耦各个...

    DDD项目实例

    1. **领域模型**:领域模型是业务逻辑的抽象,它包含了业务实体、值对象、聚合根、领域事件等元素。例如,在`MessageManager`项目中,可能会有一个`Message`实体,它包含一系列属性如发送者、接收者和消息内容,以及...

    基于DDD的Java开发模板.zip

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

    C#-DDD领域驱动设计-曹建

    5. **领域服务**:领域服务封装了跨实体或值对象的操作,这些操作不归属任何特定实体。例如,计算订单总价、验证库存等可能作为领域服务实现。 6. **数据库脚本**:项目包含的数据库脚本用于创建和初始化数据库结构...

    c# DDD(领域驱动设计)理论结合实践.rar

    10. **领域服务(Domain Service)**:处理那些不能归类到单个实体或值对象的行为,通常涉及到多个实体的协作。 11. **应用服务(Application Service)**:作为业务流程的协调者,接收外部请求,调用领域服务和...

    DDD在Java框架的例子课程.zip

    - **服务**:处理跨越多个实体或值对象的操作,不属于特定的实体或值对象。 - **Repository**:作为领域模型与数据存储之间的桥梁,提供对聚合的存取操作。 **2. Java框架下的DDD实现** - **Spring Boot**:这是一...

    2.微服务和DDD到底有什么关系?微服务如何拆分?

    在领域驱动设计(DDD)架构中,领域层是核心业务逻辑的实现层,领域服务位于领域层,为完成领域中跨实体或值对象的操作转换而封装的服务,领域服务对同一个实体的一个或多个方法进行组合和封装,或对多个不同实体的...

    微服务和DDD到底有什么关系?微服务如何拆分?

    在 DDD 中,有一些关键的概念,例如:领域对象、实体、值对象、聚合根、仓储接口等。这些概念可以帮助开发者更好地理解和设计业务领域模型,并将其拆分到多个微服务中。 在微服务架构中,DDD 可以发挥重要作用。DDD...

    Laravel开发-laravel-5.2-ddd

    领域服务是处理跨多个实体或值对象的业务逻辑的地方,不直接与数据库交互。在 Laravel 中,可以通过服务提供者注册领域服务,使其在全局范围内可用。 8. **实现示例** 以一个简单的订单系统为例,我们可以定义...

    Laravel开发-laravel-ddd

    5. **领域服务**:处理跨越多个实体或值对象的操作,不归属于任何特定实体。 6. **工厂**:创建复杂对象,隐藏其实例化过程。 7. **领域事件**:记录领域中发生的重要事情,用于解耦和异步通信。 在 Laravel 中实现...

    DDD领域驱动设计:软件核心复杂性应对之道

    "领域服务"是处理跨多个领域模型的操作,或者是不适合放在实体或值对象中的逻辑。这些服务通常代表特定业务流程,而不仅仅是数据操作。 "上下文映射"是DDD中用来管理多个领域模型之间关系的工具,它识别出不同领域...

    DDD精简版

    在描述中提到了一个博客链接,虽然具体内容未给出,但通常博主会分享关于DDD的实践经验和案例,可能包括如何定义聚合(Aggregate)、实体(Entity)、值对象(Value Object)、领域事件(Domain Event)等核心概念。...

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

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

Global site tag (gtag.js) - Google Analytics