这章的内容有什么呢?
value objects没有身份。纯粹用来描述entities模型常用属性。因为没有唯一识别,所以使用起来比较简单。
Value objects是entity的状态,描述一些entity或者它拥有的一些属性。一般为描述性,无特定意义的概念。
entities把表现放到value objects里面,来保持entities的专注。value objects是细粒度的。
DDD实践者喜欢value objects, 因为它固定不变,无副作用,易测试。下面定义了一些value objects重要的特性。
Identity-less
value objects没有身份,在domain中描述其他概念。从entity中发掘一成不变的信息,放到value objects中。value objects需要entity中一成不变的内容。
比较value objects是一个关键的操作,即使它没有身份。
Attribute-Based Equality
entities如果id相等,则被视为相同。同理,value objects因为拥有共同的value值而被认为相等。
Behavior-Rich
value objects需要尽可能多的表现面向domain的行为,封装状态。一般来说,原始的values应该默认是private的或者protected。
除非有非常好的理由打破封装的状态,让它变成公有。否则,首先考虑要把需要的方法添加到value objects里面。通过创建更加丰富的模型,让domain的概念变的更加明确。
Cohesive(拼合)
做为一个描述性的概念,它经常描述一些东西的数量,value objects经常把度量单位的值和单位拼到一起。比如钱,额度和单位。
Immutable(不可变)
值对象一旦创建,将不会被改变。如果想改变它的值,需要创建整个新的实例包含所有期望的值。这么做的原因是让不变会让操作变的简单,减少风险。
Combinable(组合)
values经常表示数字,所以在很多的cases中,把它们结合起来,创建一个新的值。值对象可以组合。虽然它是不变的,组合之后可以是一个新的value object 包含期望的值。原始的objects继续保持不变。可以通过加,减,乘,除把这些值重新结合。
Self-Validating
value objects用于不会在无效的状态中。它们会对自己的方法进行校验。
Testable
value objects不变,拼合,组合的特性,使得面向领域的语言更加易于测试。不变性 ,避免了mock的需求,或者确认副作用。拼合保证了单独的概念被充分隔离测。组合允许表达了两个value objects之间的关系。
ddd实践者,在这些年,创建了小的模式的集合 来提升跟value objects工作的经历。大多数,益处旨在提升表现力,更加的明确。一些有细小的益处,比如可维护性。这个部分代表三个基本的模式,你可以马上使用这些,思考自己的模式。
Static Factory Methods
使用静态工厂方法是一个很流行的技术用来封装复杂对象的创建,更具表现的接口。可以根据自己的风格喜好选择静态工厂方法。
Micro Types
避免原始类型,可以让你更加的明确代码的意图,导致错误因为歧义。
Collection Aversion
一些ddd的实践者认为,你将永远不会收集value objects的集合。因为原始的集合不能很好的表达domain的概念。
按理说,处理value objects最棘手的就是持久化它们。
NoSQL
很多非关系型数据库使用非规范数据,它们通过正规数据库的强大的公约进行构造。 NoSQL将有意于ddd,因为完整的实体,有时是完整的aaggreaggregates,可以被定义为单独的文档。连表问题,规范数据,orm懒加载 不会存在于面向文档模型中。value objects,意味着可以存储entity。
SQL
持久化value objects 在sql 数据库中是附带选择。 可以遵循标准sql,标准化value objects在他们自己的tables。
Flat Denormalization
持久化value objects的普通模式就是直接存储他们的值采用自定义表示。这个一个很好的选择,当你不想拥有多余的表,或者多余的声明描述去连表查它们。
Creating a Persistence Format
确保持久化的时候,重新加载值对象。值对象可以从数据库load出来,然后根据该格式进行持久化,当它保存到数据库可以采用该格式。
Persisting Values on Save
通过ORM持久化数据是最复杂的。
Persing Values on Load
Normalizing into Separate Tables