DDD领域驱动设计实战(四)-值对象(上)

简介: DDD领域驱动设计实战(四)-值对象(上)

0 前言

值对象也是领域模型中的领域对象。

应尽量使用值对象建模而非实体。即便一个领域概念必须建模成实体,在设计阶段也应更偏向于将其作为值对象。因为更容易创建、测试、使用、优化和维护。

1 为什么使用值对象?

曾经我们都滥用实体建模。在用户和权限等概念进入协作领域前,实体建模并没有带来什么坏处。在项目启动时,釆用了常用的建模方式:将领域模型中所有属性映射到对应的数据库表。并且为所有属性创建setter/getter。由于每个对象都有一个数据库主键,各个实体被组织在了一个庞大且复杂的对象网。这种建模方式是一种数据建模方式,很大程度受关系型DB影响,认为所有都需范式化,并通过外键关联引用。但其实全然面向实体的思维方法不仅没必要,而且还浪费开发时间。

在将领域概念建模成值对象时,应将通用语言考虑在内,这是建模值对象的首要原则。

那如何确定一个领域概念是否应该建模成一个值对象呢?

2 值对象的特征

  • 度量或描述了领域中的一件东西
  • 可作为不变量
  • 将不同的相关的属性组合成一个概念整体(Conceptual Whole)
  • 当度量和描述改变时,可以用另一个值对象予以替换

可以和其他值对象进行相等性比较

不会对协作对象造成副作用

当你只关心某个对象的属性时,该对象便可作为一个值对象。为其添加有意义的属性,并赋予它相应的行为。

需要将值对象看成不变对象,不要给它任何身份标识, 还应尽量避免像实体对象一样的复杂性。


在设计得当时,我们可创建和传递值对象实例,甚至在用完后直接扔了。无需担心客户端对值对象的修改。一个值对象的生命周期可长可短,就像个无害的红细胞在系统中来往。


《实现领域驱动设计》对值对象的定义:通过对象属性值来识别的对象,它将多个相关属性组合为一个概念整体。DDD中描述领域的特定方面,并且是一个没有标识符的对象。


值对象本质上就是一个集。该集合有若干如下属性


描述目的

具有整体概念

不可修改

该集合意义是在领域建模过程中,值对象可保证属性归类的清晰和概念的完整性,避免属性零碎。

3 案例

人员实体包括:姓名、年龄、性别及所在省、市、县和街道等属性。这样显示地址相关属性就很零碎。

可将“省、市、县和街道等属性”拿出来构成一个“地址属性集合”,该集合就是值对象

4 值对象的形态

4.1 业务形态

值对象是DDD领域模型中的一个基础对象,跟实体一样源于事件风暴所构建的领域模型,都包含若干属性,与实体一起构成聚合。

实体是业务对象,具有业务属性、业务行为和业务逻辑。

值对象只是若干个属性的集合,只有


数据初始化操作

有限的不涉及修改数据的行为

基本不包含业务逻辑

值对象的属性集虽然在物理上独立,但在逻辑上仍是实体属性的一部分,以描述实体的特征。


也有部分共享的标准类型的值对象,它们有自己的限界上下文及持久化对象,可建立共享的数据类微服务,比如数据字典。

4.2 代码形态

如果值对象是

  • 单一属性,直接定义为实体类的属性
  • 属性集,设计为类,包含具有整体概念的多个属性,这样的值对象无ID,会被实体整体引用

比如电商系统中的Person用户实体:

  • 有单一属性的值对象,比如id、name
  • 也包含多个属性的值对象,比如address

4.3 运行形态

除数据初始化和整体替换的行为,少有更多业务行为。

比如一个用户实体可有多个收货地址,多地址序列化后可嵌入人员的地址属性。值对象创建后不允许修改,只能用另外一个值对象来整体替换

若将值对象嵌入到实体,有如下方式:

4.3.1 属性嵌入

当引用如下之一:

  • 单一属性的值对象
  • 只有一条记录的多属性值对象的实体

4.3.2 序列化大对象

当引用一或多条记录的多属性值对象的实体时。

  • 以序列化大对象方式形成的人员实体对象,收货地址值对象被序列化成大对象JSON串后,嵌入人员实体

4.4 DB形态

设计值对象是期望转“数据建模为中心”为“领域建模为中心”,减少 DB 表的复杂度。

目录
相关文章
|
存储 自然语言处理 前端开发
领域驱动设计(DDD)-基础思想
一、序言     领域驱动设计是一种解决业务复杂性的设计思想,不是一种标准规则的解决方法。在领域驱动设计理念上,各路大侠的观点也是各有不同,能力有限、欢迎留言讨论。 二、领域驱动设计 DDD是什么 wiki释义:     领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂
7524 0
|
消息中间件 开发者
DDD领域驱动设计实战(六)-领域服务(上)
DDD领域驱动设计实战(六)-领域服务
447 0
DDD领域驱动设计实战(六)-领域服务(上)
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
229 0
|
存储 设计模式 前端开发
浅析 DDD 领域驱动设计(1)
浅析 DDD 领域驱动设计
344 0
浅析 DDD 领域驱动设计(1)
|
缓存 数据可视化 Java
浅析 DDD 领域驱动设计(2)
浅析 DDD 领域驱动设计
295 0
浅析 DDD 领域驱动设计(2)
|
设计模式 SQL 测试技术
一文理解 DDD 领域驱动设计!
以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然
一文理解 DDD 领域驱动设计!
|
数据挖掘 Java 测试技术
DDD领域驱动设计实战(三)-深入理解实体(中)
DDD领域驱动设计实战(三)-深入理解实体(中)
273 0
|
前端开发 Java 数据库连接
DDD领域驱动设计实战(03)-深入理解实体
DDD领域驱动设计实战(03)-深入理解实体
404 0
DDD领域驱动设计实战(03)-深入理解实体
|
安全 数据安全/隐私保护
DDD领域驱动设计实战(六)-领域服务(中)
DDD领域驱动设计实战(六)-领域服务
241 0
DDD领域驱动设计实战(六)-领域服务(中)
|
安全 Java 项目管理
DDD领域驱动设计实战(六)-领域服务(下)
DDD领域驱动设计实战(六)-领域服务
552 0
DDD领域驱动设计实战(六)-领域服务(下)