领域模型
对象模型中有一部分与技术完全无关,纯粹用于描述问题域中的业务实体和业务逻辑的类,它们组成了领域模型(domain model)。领域模型主要由**实体(Entity,又称为引用对象)和值对象(Value Object)**组成。
1、实体(Entity,又名引用对象Reference Object)
领域模型中,最关键的一组类是实体类。实体类用于建模问题域中的关键概念,例如顾客(Customer)、订单(Order)、账户(Account)等。实体拥有独立的生命周期,通常是有状态的,在实体的生命周期中,其属性值可以发生多次改变。
实体通过标识符(ID)来进行识别,属性值的变化无关紧要。类型和标识符相同的两个实体视为同一个实体,即使其余的属性值完全不同。标识符不同的两个实体视为不同的实体,即使其余的属性值都相同。实体的重点是通过ID表明它**“是谁”,而不是通过属性表明它“是什么样子”**。
为了思考什么是实体,思考下面的问题:
- 五岁的我和现在的我是同一个人吗?
- 一个人杀了人之后逃走了,为了逃避罪责,他染了发,整了容,改姓埋名,甚至做了变形手术。后来他被抓到了,他还是不是以前犯罪的那个人,需不需要承担杀人的后果?
上面问题的答案都是肯定的:是同一个人。人是一种实体类型。年龄、发色、相貌、姓名、甚至性别的变化都不影响他是同一个人。可以认为每一个人都有一个隐含的标识符,唯一标识了他的身份,把一个人和另一个人区分开。注意:姓名和身份证号码都不是必然的标识符,因为这些属性都是可以更改的。
实体的关键特征是:
- 拥有一个唯一且不变的标识符。通过标识符来识别相同的实体对象和区分不同的实体对象。
- 拥有独立的生命周期。
- 在实体生命周期中其状态(属性值)可以发生变化。
2、值对象(Value Object)
领域模型中还存在一类对象,它们用于描述领域实体的某个方面,而本身没有概念标识,我们关注的是它**“是什么样”而不关心它“是谁”,我们把这种类型的对象成为值对象**。它们本质上是**“披着对象外衣的值”**。
值对象的例子是电子邮箱Email
、金额Money
和订单项目OrderLine
等。值对象可以包含单个属性,例如Email
类包括一个属性address
,也可以包括两个或多个属性,例如Money
类包括amount
和currency
两个属性,OrderLine
类包括quantity、price
和product
属性。值对象的属性类型可以是简单值,也可以是其他值对象,甚至是实体。例如值对象OrderLine
类的price
属性类型是值对象Money
,而product
属性类型是实体类Product
。
值对象用于描述它所从属的实体的某个方面的属性。如同我们可以用简单值182来描述某个人(实体)的身高(以厘米表示)一样,我们可以5美元