
5.1 对象图
对象是类的实例,对象图也可看作是类图的实例。对象是面向对象系统运行时的核心,因为设计的系统在实现使用时,组成系统的各个类将分别创建对象。使用对象图可以根据需要建立特定的示例或者测试用例,然后通过示例研究如何完善类图;或者使用测试用例对类图中的规则进行测试,以求发现类图中的错误或者漏掉的需求,进而修正类图。
5.1.1 对象和类
对象图和类图一样反映系统的静态过程,但它是从实际的或原型化的情景来表达的。对象图显示某时刻对象和对象之间的关系。一个对象图可以看成一个类图的特殊用例,实例和类可在其中显示。
对象表示一个单独的、可确认的物体、单元或实体。它可以是具体的,也可以是抽象的,在问题领域里有确切的角色。换句话说,对象是边界非常清楚的任何事物。它通常包括状态、行为和标识等。
1.状态
状态也叫属性,对象的状态包括对象的所有属性(通常是静态的)和这些属性的当前值(通常是动态的)。
2.行为
对象的方法和事件可以统称为对象的行为,没有一个对象是孤立存在的。对象可以被操作,也可以操作别的对象。而行为就是一个对象根据它的状态改变和消息传送所采取的行动和所做出的反应。
3.标识
为了将一个对象与其他所有的对象区分开来,通常会给它起个名称,该名称也可以叫作标识。
类是面向对象程序设计语言中的一个概念,它实际上是对某种类型的对象定义变量和方法的原型。它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础。一个类定义了一组对象。类具有行为,它描述一个能够做出什么以及如何做的方法,它们是可以对这个对象进行操作的程序和过程。
简单了解对象和类的概念后,如下列出了对象和类的主要区别。
□ 对象是一个存在于时间和空间中的具体实体,而类仅代表一个抽象,抽象出对象的“本质”。
□ 类是共享一个公用结构和一个公共行为的对象集合。
□ 类是静态的,而对象是动态的。
□ 类是一般化,而对象是个性化。
□ 类是定义,而对象是实例。
□ 类是抽象的,而对象是具体的。
5.1.2 对象和链
对象图描述了参与交互的各个对象在交互过程中某一时刻的状态。可以认为对象图是类图在某一时刻的实例。为了绘制对象图,首先需要添加的第一个内容就是实际对象本身。
对象是真实的事物,如特定的用户、大堂或演出。对象表示符号需要两个元素,即对象的名称和描述对象的类的名称。其语法格式如下:
object-name : class-name;
上述语法中使用类名的目的是避免产生误解,因为不同类型的对象可能具有相同的名称。另外从语法中也可以看出:表示对象的方式与类几乎是一样的,其主要区别是:对象名下面要有下画线。对象名有3种表示格式,如下图所示。

上图中显示了对象名的3种表示方式,使用其中任何一种都可以。其中,第二种表示方式只有类名、冒号和下画线,该表示方式说明建立的模型适用于该类的所有实例,这种表示方式被称为匿名对象,是建模中常用的一种技术。第三种表示方式仅给出了对象名,而隐藏了属性。
另外还有一种合法的表示方式,即省略冒号和类名(换句话说,只使用对象的名称而不告知其类型),但保留了属性,该方法通过上下文可以很容易地判别出对象的类型。如下图所示演示了学生类与学生对象stu。

在上图中表示学生类的stu对象时不仅给出了对象名,还给出了该对象的属性和相应的值。
对于每个属性,类的实例都有自己特定的值,它们表示了实例的状态,在UML图中显示这些值有助于对类图和测试用例进行验证。在UML的对象表示法中,对象的属性位于对象名称下面的分栏中,这与类的表示法是类似的。属性的合法取值范围由属性的定义确定,如果类的定义允许,属性的取值为空也是合法的。
提示
后面的章节还会介绍其他的图,所有的交互图中使用的都是相同的对象表示符号。
对象不仅拥有数据,还可拥有各种关系,这些关系被称为链。对象可以拥有或参与的链是由类图中的关联定义的,也就是说,与类定义某种类型的对象一样,关联也定义了某种类型的链。换句话说,对象是类的实例,而链是关联的实例。
如果两个对象具有某个关联定义的关系,则称它们被链接起来。一条连接两个对象的直线就表示这两个对象所具有的链。链有3种命名方法,分别如下。
□ 使用相应的关联命名。
□ 使用关联端点的角色名命名。
□ 使用与对应类名一致的角色名命名。
在命名对象间的链时,可以根据具体情况使用以上3种方法中的任何一种。例如,下图中表示Venue对象“holds”和Event对象,除此之外,该图中还包含两个Performance对象,这两个对象和Event之间的链使用与类名一致的角色名称描述,另外holds表示关联的名称。

5.1.3 对象图概述
对象图(Object Diagram)就是类图的实例,它描述的是参与交互的各个对象在交互过程中某一时刻的状态,它可以看作是类图在某一时刻的实例。对象图提供了系统的一个“快照”,显示在给定时间实际存在的对象以及它们之间的链接,可以为一个系统绘制多个不同的对象图,每个对象图都代表系统在一个给定时刻的状态。对象图展示系统在给定时间特有的数据,这些数据可以表示各个对象、在这些对象中存储的属性值或者这些对象之间的链接。
由于对象是类的实例,所以对象图中使用的符号和关系与类图中使用的相同,绘制对象图有助于理解复杂的类图。对象图不需要提供单独的形式。类图中就包含了对象,所以只有对象而无类的类图就是一个对象图。
从某种情况来说,对象图也是一种结构图。它可以用来呈现系统在特定时刻的对象(Object),以及对象之间的链接。在UML中,由于对象为类的实例,所以对象图可以使用与类图相同的符号和关系。如下图所示为一个对象图的简单示例。

在上图中,Customer类的对象cusOrder拥有两个订单对象,本示例中对这3个对象都进行了赋值。从上图中可以看到,对象图包含属性分栏,这是因为对于每个属性,不同的对象会拥有不同的值;由于类的操作是唯一的,所以拥有该属性的某个类的对象也会拥有该类的相同操作,如果对象图中再包含操作,则会显得多余,因此对象图中不能包含相关操作。
1.对象图的表示方法
对象图一般包括两部分:对象名称和属性。它们是绘制对象图的关键。对象名称和属性的表示方法如下。
□ 对象名称 如果包含了类名,则必须加上“:”。另外,为了和类名区分,还必须加上下画线。
□ 属性 由于对象是一个具体的事件,因此所有的属性值都已经确定,因此通常会在属性的后面列出其值。
2.阅读对象图
上图中已经在UML中绘制了一个对象图,那么如何对对象图进行阅读呢?很简单,其主要步骤如下。
(1)首先找出对象图中所有的类,即在“:”之后的名称。
(2)整理完成后通过对象的名称来了解其具体含义。
(3)按照类来归纳属性,然后再通过具体的关联确定其含义。
3.绘制对象图
前面已经绘制了简单的对象图,下面来看绘制对象图的主要步骤。
(1)先找出类和对象,通常类名在“class”“new”和“implements”等关键字之后,而对象名通常在类名之后。
(2)对类和对象进行细化的关联分析。
(3)绘制相应的对象图。
4.对象图的应用说明
下面从两个方面对对象图的绘制过程进行说明。
1)论证类模型的设计
当设计类模型时,相关人员可以通过对象图来模拟出一个运行时的状态,这样就可以研究在运行时设计的合理性,同时也可以作为开发人员讨论的一个基础。
2)分析和说明源代码
由于类图只展示了程序的静态类结构,因此通过类图看懂代码的意图是很困难的。因此,在分析源代码时,可以通过对象图来细化分析,而开发人员处理逻辑比较复杂的类交互时可以绘制一些对象图进行补充说明。
5.对象图用途
对象图的用途有很多,其主要用途如下所示。
□ 捕获实例和连接。
□ 捕获交互的静态部分。
□ 在分析和设计阶段进行创建。
□ 举例说明数据/对象结构。
□ 详细描述瞬态图。
□ 由分析人员、设计人员和代码实现人员开发。
提示
对象图不显示系统的演化过程,如果要显示系统的演化过程,可以使用带消息的合作图,或用顺序图表示一次交互。
5.1.4 对象图和类图的区别
类图是描述类、接口、协作以及它们之间关系的图,用来显示系统中各个类的静态结构。对象图描述的是参与交互的各个对象在交互过程中某一时刻的状态。对象图是类图的实例,它几乎使用与类图相同的标识。类图和对象图之间有多个不同点,其具体说明如下表所示。

5.1.5 使用对象图测试类图
对于比较复杂的类图来说,它很有可能是不正确的,因此需要使用另外的UML图对其进行测试,如对象图。使用对象图对其测试的过程中有可能会发现一些错误,然后可以针对这些错误对类图的修改提出建议。
本节以一个简单的电影售票系统为例,首先绘制最基本的类图,然后通过构造对象图作为对类图的测试。从测试过程中可以看到构成对象图的模型元素以及对象图是如何被作为测试用例来使用的。下图演示了该系统中关于售票协议与座位的一个简单类图。

在上图中可以看出每个售票协议可以分配不少于一个座位,而每个座位只能和一个销售协议进行关联。根据上图的类图来绘制对象图,首先创建一个新的SalesAgreement对象以及两个Seat对象,每个Seat对象都由SalesAgreement对象来支配,如下图所示。

1.未分配的Seat对象
从上面的2个图中可以看出,每个Seat对象都会被一个SalesAgreement对象所支配,但是通过调查后发现有些座位没有被工作人员销售出去过,而是直接给观众的。重新绘制对象图,在该图中添加一个新的Seat对象,该对象不会被任何的SalesAgreement对象所支配,如下图所示。

如果上图中所绘制的对象图是正确的,则需要更改基本类图,更改后的类图如下图所示。

在上图中允许一个Seat对象被0个或1个SalesAgreement对象支配。
2.多份销售协议对应一个座位
一个座位是否可以被多个销售协议所分配呢?如果查看系统的相关销售数据,大家可以发现这是可能的。例如2012年10月1号这一天,座位3502被分配过,那么2012年10月2号或其他时间该座位也可以被分配。重新绘制对象图,在该对象图中允许Seat对象被多个SalesAgreement对象所支配,如下图所示。

从上图中可以看出,SalesAgreement对象的属性值是日期,这两个SalesAgreement对象的日期是互不重叠的,即在同一个时间分配相同的座位是不合法的。另外,从上图中也可以得到其他信息,如一个座位可以被多个而非仅仅一个销售协议支配。
重新更改该系统的类图,更改后的效果如下图所示。

从上图中可以看出0个或多个SalesAgreement对象可以分配相同的Seat对象,同时也对SalesAgreement对象添加了约束,该约束规定SalesAgreement对象支配Seat对象的时间必须是不重叠的。