您的位置:首页 > 移动开发 > Objective-C

ddd的战术篇: domain object之一

2018-02-16 17:10 176 查看
首先ddd的战术这个讲法是不太好的。ddd书中说的是战术性建模(tactical modeling)。其意思是在战术层面的建模,那当然有战略层面的建模啦。以后会专门讲。

domain object是ddd区别于其他建模/设计方法的一个部分。他定义了概念帮助我们去建立model。如果没有接触过ddd,一开始会觉得有点莫名其妙,为什么要定这种规矩,这种规则?


Entity,value object, Aggregate


entity

entity是一类可识别的可追踪的对象。

说简单了,它必须有identifier,再简单点id(可识别,可被追踪)。

另外它是有可变对象,mutable。但即使状态变化了之后,entity还是原来的entity。(好绕口)

  现实一点的例子。一个人家“王帝”,他改名交了“王皇”,名字虽然变了,但还是同一人。当然现实世界里我们很难去寻找一个identifier(识别码),如何定义一个不变的identifier会是个哲学问题,但编程时就简单多了,直接搞个id就就行。


value object

与entity对应的一个概念叫value object

它是一个值,是不可变的,immutable。没有identifier,也不需要被追踪!

  比如java中的字符串和value object的感念很相近。字符串生成之后就是不可变的。而且也没有什么id来识别它。

什么时候使用entity,什么时候使用value object

具体问题具体分析

比如我们需要对地址这个东西建模。如果我们关心的是地址的履历之类的信息,过去30年前这个地址可能叫霞飞路,现在可能叫淮海路,而且需求是我们必须知道霞飞路,淮海路指的是一个地址。那很可能我们需要的是entity。这个entity可能还要开发change()的方法来改变路名。

但如果我们做的是一个送货软件。地址只是表示一个目的地而已,霞飞路和淮海路在我看来就是不同的,那就说明,你不必对地址本身的变化进行追踪(送货地址变了,对你很重要。但霞飞路改名成淮海路对你不重要。)。那value object就够了。

  你可能觉得何必这么费事搞个表示地址的value object, 搞个字符串不就行了?

   首先这不一定是一个关于ddd的问题。淡然很多情况下,我们可以的确用java的基础类来建模的。但从面向对象的封装角度来说,我们可以考虑创造专门的类。

   如果我们创建value object,它是可以拥有行为的。比如Address是一个value object。它可以拥有getCountry(), getProvince(), getCity()等方法。


Aggregate

Aggregate,集合。是有多个(也可以是一个)entity,value object组成的对象。

Aggregate可以看作一个树状结构的东西。根是一个entity。Aggregate的一个作用是保持domain object的关联性的正确。


Aggregate和Repository


Repository

Repository是用来存放一个aggregate的object。(是不是听起来像DAO?)

Repository的存在,让我们感觉我们存放在它里面的aggregate就好像on memory一样,不必去关心它具体是和rdb对接还是其他的形式。

请注意的是Repository对应的是aggregate而不是entity!虽然我们在实际偏码时不会去专门写aggregate的类,有关具体实现,之以后的文章会写。简单地讲根entity就可以代表aggregate。



domain object的做法与active record的区别

active record pattern也是很常见的一种模式。大概是建立于数据表的一一映射的类,然后有各自的DAO类。乍看起来和domain object的做法是一样的。

1. 映射关系

active record一般以一个类对应一个数据表为前提

repository则没有这个限制。当一个aggregate需要对应多个数据表时,那repository自然就对应多个数据表。repository隐藏了数据层的物理实现。

这里想多提一点。domain model的建立,称作理论设计比较合适。它尽量不关心物理的实现,只求对domain的正确反映。

而data model的设计,可以称作物理实现。是以数据永久化为目的。与ddd相关联,自然就是如何将domain object永久化。

2. domain object主张充血模式

active record常常会导致制造大量的于数据表对应的类,这些类一般不会有行为,而描述业务逻辑的职责就会到很多service类上。

domain object则希望类有自己的行为,而不是开放好多setter,让外部的类来控制自己的状态变化。


总结

讲了好多理论,大致介绍了domain object。

entity: stateful, mutable.

value object: immutable

aggregate: entity和value object的集合

repository: stateless,储存aggregate

之后的文章准备写一些例子来更好地说明这些概念。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息