5.1 关联#
设计领域模型时, 确定每个领域对象之间的关联非常重要。
-
双向关联:两者互相引用
-
单项关联:谁持有谁。 例如“美国总统”包含了“华盛顿”、“奥巴马“。 一般是一对多的情况。
设计上没必要让奥巴马去指向美国,因为奥巴马只能是一个国家的总统, 我们不需要通过奥巴马的身份去获知它属于哪个国家的总统,
即我们一般有county.getPresident() 而不会有 president.getCountry()。 (当然并不是说不存在查询人的国家,只是对于当前这个总统系统来说,没必要,并不是全球人口普查系统)
-
限定的关联:某个特定条件下的单向关联。 例如 1790年的美国总统是华盛顿, 这里国家+时间周期 ->总统
对应代码就是 Person person = country.getPresident(period)
书里的另一个例子: account.getInvestment(String stock) 股票系统里,每个股票对应一个投资。
假设大数据集群里有很多的节点组,节点组里有很多的节点
我们不需要给他们画双向箭头, 那应该都是单向的。
如果不存在指定关系,则不用加限定。
另
5.2 实体Entity(又称 ReferenceObject)#
一个对象并不是由它的属性定义的, 因为它的属性在生命周期中可能会变化。 而且不同对象的属性可能相同。
因此定义对象的核心是“标识”。
被标识定义的对象叫做Entity实体。
实体要满足的2个条件:
- 它在整个生命周期中具有连续性
- 它的区别并不是由哪些对用户非常重要的属性决定的。
并不是所有事物都需要标识。
比如2笔500元的银行流水, 他们的流水号代表了是不同的流水, 而500元这个金额则没必要加标识。
标识在设计中也要确认一下是否有用。
比如 演唱会如果指定位置,则座位就必须有一个座位号标识用于识别门票上的座位
但如果演唱会不指定位置,先到先得,那么座位就仅仅代表了一个位置, 不需要标识,也就不代表是一个实体。
5.2.1 entity建模#
在核心实体中,添加和核心实体强一一关联的属性或者行为。
即如果可以通过某1-x个属性,能直接关联到这个实体,那么这个核心属性可以放到实体中。
比如可以通过姓名加电话,唯一定位到一个人的画,那应该放在人实体里作为属性(这样可以后面用来getPeople(phone, name) 来获取一个唯一人)
但如果人有多个电话,而且给了不同的人留下了不同的电话, 那么电话要从人的属性里删去, 放到另一个新的实体“联系人”中, 联系人中记录了每个人对每个人的联系方式。
最常见的entity标识经常用UUID自动生成实现。 但有时候客户可能不想看到ID, 只想根据例如名字、地点确定某一个事物,则
如果多个系统间要共用某个实体,担心各自生成ID的话会有问题,可以借助第三方机构来生成。例如2个医院之间病人想互通,则一般用身份证号来作为实体核心,而不会用医院病历号来区分。
5.3 值对象ValueObject#
为所有的实体都加上唯一标识,会影响系统性能增加分析工作量,使模型变得混乱。
因此在系统里可以不需要标识的对象, 称之为 值对象(ValueObject)
我们只关心他们是什么, 不关心他们是谁。
比如节点规格就是一个值对象。
对于地址, 如果是邮寄系统, 地址仅仅是一个值对象。 但如果是电力系统,要根据地址单独收费,则地址是一个实体。