TDD-软件中所表示的模型

Tags: TDD, 领域驱动开发模式, Entity模式, Value Object模式, Service模式

一、 关联

对象之间的关联使得建模与实现之间的交互更为复杂。

一个显示了顾客与销售代表之间关联的模型有两个含义。一方面,它把开发人员所认为的两个真实人之间的关系抽象出来。另一方面,它相当于两个java对象之间的对象指针,或者相当于数据库查询的一种封装。
例如,一对多关联在实例变量中可以用一个集合来实现。也可以使用一种访问方法来查询数据库,找到相应的记录,并用这些记录来实例化对象。在设计中必须制定一种特殊的遍历机制,这种遍历的行为应该于模型中的关系一致。
现实生活中有大量的“多对多”关联,其中有很多关联自然而然是双向的。这些普遍的关联会使实现和维护变得很复杂。此外,他们也很少能表示出关系的本质。

至少有三种方法可以使关联更易于控制。

1) 规定一个遍历方向
2) 添加一个限定符,以便有效的减少多重关联。
3) 消除不必要的关联。

尽可能地对关系进行约束是非常重要的。双向关联意味着只有将这两个对象放在一起考虑才能理解他们。当应用程序不需要双向遍历时,可以指定一个遍历方向,以便减少相互依赖性,并简化设计。理解了领域之后就可以自然的确定一个方向。国家与总统的关联Brokerage Account中的关联

二、 模式:Entity

一些对象主要不是由它们的属性定义的。它们实际上表示了一条“标识线”,这条线经过了一个时间跨度,而且对象在这条线上通常经历了多种不同的表示。有时,这样的对象必须与另一个具有不同属性的对象相匹配。而有时一个对象必须与具有相同属性的另一个对象区分开。错误的标识可能会破坏数据。

主要由标识定义的对象称为Entity。Entity(实体)有特殊的建模和设计思路。它们具有生命周期,这期间它们的形式和内容可能发生根本改变,但其标识保持不变。模型必须定义出“符合什么条件才算是相同的事物”。在现实世界中,并不是每个事物都必须有一个标识,标识重不重要,完全取决于它是否有用。实际上,现实世界中的同一个事物在领域模型中可能需要表示为Entity,也可能不需要表示为Entity。例如:体育场的座位。

Entity建模

当对一个对象进行建模时,需要考虑它的属性和行为。但Entity的最基本职责是确保连续性,以便使其行为更清楚且可预测。保持实体的简练是实现这一职责的关键。不要将注意力集中在属性和行为上,应该摆脱这些细枝末节,抓住Entity对象定义的基本特征,尤其是那些用于识别、查询和匹配对象的特征。只添加那些对概念至关重要的行为和这些行为所必需的属性。此外,应该将行为和属性转移到与核心实体关联的其他对象中。在这些对象中,有些可能是Entity,有些可能是Value Object。除了标识问题之外,实体往往通过协调其对象的操作来完成自己的职责。

设计标识操作

每个Entity都必须有一种建立标识的操作方式,以便与其他对象区分开,即使这些对象与它具有相同的描述属性。两个对象是同一个事物时意味着什么?我们很容易为每个对象分配一个ID,或是编写一个用于比较两个实例的操作,但如果这些ID或操作在领域中并没有显著的区别,那么只会使问题更混乱。这就是分配标识的操作通常需要人工输入的原因。例如:支票薄对账软件可以提供一些可能匹配的账目,但它们是否真的匹配则要由用户最终决定。

三、 模式:Value Object

很多对象没有概念上的标识,它们描述了一个事务的某些特征。用于描述领域的某个方面而本身没有概念标识的对象称为Value Object(值对象)。Value Object被实例化以后用来表示一些设计元素,我们只关心这些元素是什么,而不关心它们是谁。“地址”是Value Object吗?当我们只关心一个模型元素时,应把它归类为Value Object。我们应该使这个模型元素能够表示出其属性的意义,并为它提供相关功能。Value Object应该是不可变的。不要为它分配任何标识,而且不要把它设计成像Entity那么复杂。Value Object所包含的属性应该形成一个概念整体。例如,street,city和postal code不应该是person对象的单独属性。它们是整地址的一部分,这样可能使得Person对象更简单,并使它成为一个更连贯的Value Object。

设计Value Object

我们并不关心使用的是Value Object的哪个实例。由于不受这方面的约束,设计可以获得更大的自由,因此可以简化设计或优化性能。在设计Value Object时有多种选择,包括复制、共享或保持Value Object不变。
共享和复制哪个更划算取决于实现环境。

四、 模式:Service

在某些情况下,最清楚、最使用的设计会包含一些特殊的操作,这些操作从概念上讲不属于任何对象。与其把它们强制地归于哪一类,不如顺其自然的在模型中引入一种新的元素,这就是Service(服务)。一些领域概念不适合被建模为对象。如果勉强的把这些重要的领域功能归为Entity或Value Object的职责,那么不是歪曲了基于模型的对象的定义,就是人为地增加了一些无意义的对象。Service是作为接口提供的一种操作,它在模型中式独立的。所谓Service,它强调的是与其他对象的关系。与Entity和Value Object不同,它只是定义了能够为客户做什么。Service是以一个活动命名,而不是以一个Entity命名,也就是说它是动词而不是名词。

Service的参数和结果应该是领域对象。好的Service有以下3个特点:

1) 与领域概念相关的操作不是Entity或Value Object的一个自然的部分。
2) 接口是根据领域模型的其他元素定义的。
3) 操作是无状态的。

这里所说的无状态是指任何客户都可以使用某个Service的任何实例。

Add a Comment