小言_互联网的博客

UML统一建模实用教程 第三章 类图

432人阅读  评论(0)

第三章 类图

目录:


3.1 类的表示

1.类图

类图是描述类、协作(类或对象间的协作)、接口及其关系的图。与所有UML的其它图一样,类图可以包括注释、约束、包。
类图中的关系包括:依赖关系(Dependency)
泛化关系(Generalization)
关联关系(Association)
实现关系(Realizetion)

图3-1 电子商务网站的对象模型

2.类图的作用

(1)为系统词汇建模型
(2)模型化简单的协作
(3)模型化一个逻辑数据库模式
(4)类图的组成元素
类图中的元素有类、接口、协作、关系、注释、约束、包。关系把类、协作、接口链接在一起构成一个图。注释的作用是对某些类和接口进行注释,约束的作用是对某些类和接口进行约束。

3.2 类图中的关系

3.2.1 类的表示

UML中,表示一个类,主要是标识它的名称、属性和操作。如图3-2所示,类由一个矩形表示,它包含3栏,在每栏中分别写入类的名称、属性、操作。

图3-2 Order类

1.名称

类名称不可同名。名称(Namre)是一个文本串。

2.属性

属性描述了类的静态特征,在面向对象编程中,把属性表示为成员变量。在属性的面前有一个修饰,用来表示属性的可见性,属性的可见性一般都是private,这样才符合面向对象的“封装”思想。

3.操作

操作是类所提供的服务,通俗的说,操作就是定义了对象所能做的事情。在面向对象编程语言中,它通常表示为成员方法。

4.职责

职责指类承担的责任和义务。在矩形框中最后一栏中写明类的职责。

图3-3 职责的表示

5.约束

约束指定了类所要满足的一个或多个规则。在UML中,约束是用花括号括起来的自由文本。

图3-4 约束的表示

3.2.2 类的种类

1.抽象类

在进行类设计时,如果一些具体类具有相同的方法或属性,我们可以把这些相同的方法或属性从这些具体类中抽取出来,把它们封装到一个抽象类中,然后扩展抽象类,重新定义这些具体类。
抽象类是一种不能直接实例化的类(不能用抽象类创建对象)
在UML中,抽象类和抽象方法的表示是将其名字用斜体表示。草图中用《abstract》构造型来表示。

图3-5 抽象类的2种表示方法

2.接口

接口是一种类似于抽象类的机制,接口中的方法都是抽象方法。在UML中,接口有两种表示方法,如下图所示

3.关联类

在应用当中,我们发现两个类之间具有多对多的关系,并且有些属性不属于关联两端任何一个类,例如,在某个应系统中有两个类:person(人)和institute(协会),显然persong可以属于多个institute,而每个institute肯定会吸纳很多person。因此它们之间很显然就是一个多对多的关系。

如果要记录每个person在所属的institute所担任的职务,应该把这个职务属性放在哪个类中呢?这个属性既不属于person,也不属于institute。显然,这个属性应该放在关联类中(Role),如图3-6所示。

图3-6 关联类Role

4.模板类

在注入c++这样语言中,提供了一种叫做参数化类(parameterized class)的机制,或叫做模版(template)。例如,我们需要一些能过处理整型、浮点型、字符串的数组,普通的做法是为它们各创建一个类,这三个类除了数据类型不同之外,其他的都是相同,但是仍然要定义三次。
模版就是用来解决这个问题,可以根据占位符或者参数来定义类,而不用说明属性、方法返回值和方法参数的实际类型。通过实际值代替占位符即可创建新类。这样,就可以采用如图3-7所示的设计方案

图3-7 模板类

5.主动类

从运行的角度来看,还有一种特殊的类-主动类,主动类的实例称为主动对象,一个主动对象拥有一个控制线程并且能够控制线程的活动,具有独的控制权。
例如,命令处理程序就是一个主动类的例子,它从外面接受命令对象,然后在自身的控制线程内执行命令。在第二章中,曾经说明UML1.0中主动类的表示方法(普通类的基础上加上粗边界),但是在UML2.0中修改了主动类的表示法(在类的两边加上垂直线)

6.嵌套类

在诸如Java的语言中,允许你将一个类的定义放在另一个类定义的内部,这就是嵌套类,在Java中也称为内层类。嵌套类是声明在它的外层类中的,因此只能够通过外层类或外层类的对象对它进行访问 ,在UML中,可以采用一个描图标来表示这种关系,如图3-9所示。

图3-8 嵌套类表示法

3.3 如何阅读类图和绘制类图

3.3.1 关系分类

分为4种,依赖关系、泛化关系、关联关系、实现关系

1.依赖关系

表示两个或多个模型元素之间语义上的关系,客户元素以某种形式依赖于提供者元素。实际上,关联、实现、泛化都是依赖关系。

图3-9 依赖关系
• 依赖关系可以细分为4大类:使用依赖、抽象依赖、 授权依赖、 绑定依赖。

(1). 使用依赖

• 表示客户使用提供者提供的服务,以实现它的行为,下面都属于使用依赖的具体形式:
• 使用(《use》)
• 调用(《call》)
• 参数(《parameter》)
• 发送(《send》)
• 实例化(《instantiate》)

(2).抽象依赖

• 表示客户与提供者之间的关系,客户与提供者属于不同的抽象事物,具体依赖形式:
• 跟踪(《trace》)
• 精化(《refine》)
• 派生(《derive》)

(3).授权依赖

• 表达一个事物访问另一个事物的能力,具体依赖形式:
• 访问(《access》)
• 导入(《import》)
• 友元(《friend》)

(4).绑定依赖

• 绑定依赖属于较高级的依赖类型,用绑定模板以创建新的模型元素,具体依赖形式:绑定(《bind》)

2.泛化关系

是从特殊元素到一般元素的分类关系称为泛化关系。模型元素可以是类、用例以及其他。

图3-10

3.关联关系

关联关系是较高层次的关系,它具体包括聚合关系和组合关系。

(1)聚合关系

例如,大学由多个学院组成。

图3-11

(2)组合关系

例如,窗口中的菜单和按钮不能离开窗口独立存在,因此,是组合关系。

图3-12

注意:在Rose中表示组合的符号与在UML标准中表示组合的符号有区别。如下图所示

4.实现关系

类与被类实现的接口、协作与被协作实现的用例都是实现关系。

图3-13

3.3.2 关联的属性

关联关系是比较抽象的高层次关系。关联的属性包括名称、角色、多重性、限定、导航。

1.名称

可以使用一个动词或动词短语给关联取名,用来描述关联的性质。在描述关联时,关联的名称并不是必需的,在关联名和角色中选一即可。可以在关联上标识阅读方向的方向指示符,以消除阅读的歧义。
下面的例子表示,关联名称是”使用” ,即用户使用计算机。

图3-14 关联名称

2.角色

在关联关系中,角色表明了关联的每一端在关联中承担的职责,即,关联发生时,关联的每一端在关联中扮演的角色。角色的名称应该是名词或名词短语,以解释对象是如何参与关联的。如图3-16关联的角色。

图3-15 关联的角色
学生在关联中,扮演的是学习者的角色;学校扮演的是教学者的角色。

3.多重性

多重性就是某个类有多少个对象可以和另外一个类的单个对象关联。

图3-16
上图的多重性表示:一个学校可以有多个学生学习;一个学生可以到多个学校学习,或者不去任何一个学校学习。

4.导航性

导航性描述了源对象通过链接访问目标对象。箭头表明了导航的方向性,即只有源对象才能访问目标对象,反之,目标对象不能访问源对象。

图3-17

5.限定符

如果源对象到目标对象是1对多关联,为了在多个目标对象的集合中查找到需要的目标对象,我们必须在目标对象集合中,选一个唯一标识目标对象的查找键(限定符,从目标对象的属性中选择),它应该是目标对象中的某个属性,当然,也可以是表达式。
一个俱乐部(Club)可以有多个成员(Member),为了在成员集合(目标对象)上找到需要的对象,我们选择memberId作为查找关键字,即,限定符。

3.3.3 阅读类图

以电子商务为例

1.电子商务网站业务

(1)电子商务网站

假设住在厦门的张三要给住在绍兴的朋友李四送一个生日蛋糕,由于它们之间的距离太远,不可能亲自买一个送过去。但解决这个问题并不难,张三登录到一个电子商务网站购买一个,并通过该网站将其送给李四。而这个电子商务网站实际上就是通过绍兴的蛋糕店来完成这个任务的。因此,在整个传递过程中,各个实体之间的关联关系如图3-18所示。

图3-18

• 现实生活中的情况要比这个复杂得多,电子商务网站可以接受很多人的订单,也可以与不同地方的蛋糕店形成合作,以送给更多不同地方的人。因此,其可以像图3-18那样进行抽象(为了使例子简单,在此略去了“送货人”)。

• 在图3-19中,很好地诠释了类和对象的概念。显然张三就是一个对象,它可以归位“订货人”这个类中;而绍兴蛋糕店显然也是一个对象,它可以归到“商户”这个类中。

• 例如在上面的例子中,订货人把想完成的事(给李四送蛋糕)委托给电子商务网站,而电子商务网站又委托给具体的商户(绍兴蛋糕店),具体的商户最终通过送货人完成了这个行为。

• 那么在实际的过程中,整个行为是怎么动起来的呢?张三在电子商务网站填写信息,电子商务平台向商户发信息,商户指挥送货人完成该动作。

图3-19 抽取业务模型

(2)建立对象模型

实际上,电子商务网站的对象模型(图3-20)就是对图3-18电子商务业务建模的结果

图3-20电子商务网站的对象模型
在阅读这些简单的类图时,重点在于把握三项内容:类、关系、多重性。其阅读的顺序应该遵循以下原则:
首先搞清楚每个类的语义,其次理解类间关系,第三,结合多重性来理解类图的结构特点以及个个属性和方法的含义。下面来阅读图3-20电子商务网站的对象模型

<1>.理解类的语义

该图包含七个类:
order(订单)
orderitem(订单项)
customer(顾客)
consignee(收货人)
deliverder(送货单)
peddlery(商户)
product(产品)
并且每个类都定义了若干属性和方法

<2>.分析类关系

• order和orderitem之间是组合关系,根据箭头方向可致是orderitem组合为order。这就是说order包含了orderitem。

• order和customer、consignee、deliverder是关联关系,即一个订单和客户、收货人、送货单是相关的

• 第二复杂关系的类就是deliverorder(送货单),和它相关的也有四个类:order、orderitem、consignee、peddlery,即表示送货单与订单是相关的,同时还关联到订单项。另外,与商户、收货人的关联关系也是显然的。

• product(产品),与它关联的类是peddlery、orderitem,显然产品属于某个商户的,订单项中必须指出是那种商品。

<3>.分析关联的多重性

多重性用来说明关联的两个类之间的数量关系。
• order类包含了两个方法:dispatch()和close(),它们分别实现“分拆订单生成送货单”和“完成订单”。

• 在deliveorder()类中有一个close()方法,同理它表示“完成订单”。

• 在orderitem中有一个statechange()方法和deliverstate,它们是用来改变其“是否交给收
货人”标志位的。

• 我们来阅读一下:先调orde的dispatche()方法,它将根据包含的orderitem中的产品信息来按供应商分拆成若干个deliverorder。商户登录系统后即可获取deliverorder,并执行完后调用close()方法。这时,将调用orderitem的statechange()方法来改变其状态。同时,再调用order的close方法。判断该order的所有的ordeitem是否都送到了,如果是就其close()掉。
通过上面的分析,我们将对象图的关联分析列在表3-1中
表3-1关联的两个类之间的数量和语义关系

对图3-20的类图进行精化:除了引入personal和company两个类之外,还增加了关联属性、约束、注释。这些东西能更具体的描述类图。得到了如图3-21所示的类图

图3-21 辅助元素的类图

<4>关联的导航性

我们将图3-20中的关联进一步具体化为导航箭头。对象的消息只能沿着导航箭头的方向发送给另一对象。例如,可以从对象order向对象consignee导航,但不能从consignee向Order导航。通俗的说就是在Order中可以获取其相应的Consignee,而从Consignee不能了解Order。如果没有箭头,则表示是双向关联的,也就是等价于两端都有箭头,即可互相导航。

<5>.关联的角色名

在图3-21中,
在customer和order的关联中,customer端有一个“+owener”字符串;
在order到consignee;peddery到deliverorder再到product之间也有类似的字符串。
这些字符串称为角色名称,表示customer是order的所有者(owner),order包含(including)了consignee,peddlery是product的提供者,是deliverorder的执行者。
通过理解这些角色名称,使得类之间的关联关系更加具体化。

<6>.关联的限定符

图3-21中,在order和orderitem之间的组合关系中,orderitem端多了一个方框,里面写着productId,它在UML中称为限定符。存在限定符的关联称为受限关联,用来表示某种限定关系。
在本例中,它的用途是说明对于一张订单,每种产品只能有一个订单项。

<7>.约束

a) 在图3-21中,在order类的边上有一个用大括号括起的文本,里面写着“只有当所有的orderitem()已经送到,才将close()成功”,而在persongal和company类当中则有一根虚线,上面写着“{xor}”.

b) 在UML类图中。这种以大括号括起来的、放在建模元素外边的字符就是约束。正如第二章曾经说过的,约束可以自由文本和OCL两种形式表示。在本例中,这两个都是自由文本。

c) 前一个约束显然是表示一种规则,也就是说每送完一个deliverorder,就会将其所包含的orderitem的deliverstate修改为ture;而对于order,调用close()成功的前提是它所包含的所有orderitem的deliverstate的值都是ture才行。
d) 而后一种约束则是一种关联间的约束,它表示一个customer 要么是personal(个人用户),要么是company(公司客户)。

<8>.职责

每个类都有其要承担的职责,有时,应该在类图上标出类的职责。通常采用的方法有两种:一种是在类的原有的分栏中添加注释行(也就是以“――”开头的字符串);另一方法则是新增一个分栏。但在rose中,对于后者没有提供默认的支持。

<9>.导出属性

a) 在Order类中有一个名为price的属性,它前面加了一个“/”符号,这在UML模型中是用来表示导出(deried)属性的。 导出属性的是指可以根据其他值计算出来的属性

b) 为了说明order类中的这个导出属性是如何计算出来的,还特意为其添加了一个注释。并在注释中写到:price=sum(all orderitem.price),意思是这里的price属性的值应该等于所有的orderitem类的price字段值的总和。

3.3.4 实践建立对象模型

例子

李小平是一个爱书之人,家里各类书籍已过千册,而平时又时常有朋友外借,因此需要一个个人图书管理系统。该系统应该能够将书籍的基本信息按计算机类、非计算机类分别建档,实现按书名、作者、类别、出版社等关键字的组合查询功能。在使用该系统录入新书籍时系统会自动按规则生成书号,可以修改信息,但一经创建就不允许删除。该系统还应该能够对书籍的外借情况进行记录,可对外借情况列表打印。另外,还希望能够对书籍的购买金额、册数按特定时限、周期进行统计。
我们以问题陈述为输入信息,采用“名词动词法”寻找分析类。名词动词法的主要规则是从名词与名词短语中提取对象与属性;从动词与动词短语中提取操作和关联。

1.找备选类

首先。可以逐字逐句地阅读上面那段需求描述,并将其中的所有的名词及名词短语列出来,可以得到备选类列表。

2.从备选类中筛选出候选类

并不是所有的备选类都是适合候选类,有些名词对于要开发的系统来说无关紧要。甚至不属于系统;而有些名词表述的概念则相对较小,适合某个候选类的属性。因此,需要对备选类进行一番筛选,将这些不适合的排除掉。

(1)“李小平”、“人”、“家里”很明显是系统外的概念,无须对其建模;

(2)而“个人图书管理系统”、“系统”指的就是将要开发的系统,即系统本身,也无须对其进行建模;

(3)很明显“书籍”是一个很重要的类,而“书名”、“作者”、“类别”、“出版社”、“书号”则都是用来描述书籍的基本信息的,因此应该作为“书籍”类的属性处理,而“规则”是指书号的生成规则,而书号则是书籍的一个属性,因此“规则”可以作为编写“书籍”类构造函数的指南。

(4)“基本信息”则是书名、作者、类别等描述书籍的基本信息统称,“关键字”则是代表其中之一,因此无需对其建模;

(5)“功能”、“新书籍”、“信息”、“记录”都是在描述需求时使用到的一些相关词语,并不是问题域的本质,因此先可以将其淘汰掉;

(6)“计算机类”、“非计算机类”是该系统中图书的两大分类,因此应该对其建模,并改名为“计算机类书籍”和“非计算机类书籍”,以减少歧义;

(7)“外借情况”则是用来表示一次借阅行为,应该成为一个候选类,多个外借情况将组成“外借情况列表”,而外借情况中一个很重要的角色是“朋友”—借阅主体。虽然到本系统中并不需要建立“朋友”的资料库,但考虑到可能会需要列出某个朋友的借阅情况,因此还是将其列为候选类。为了能够更好地表述,将“外借情况”改名为“借阅记录”,而将“外借情况列表”改名为“借阅记录列表”;

(8)“购买金额”、“册数”都是统计的结果,都是一个数字,因此不用将其建模,而“特定时限”则是统计的范围,也无需将其建模;不过从这里的分析中,我们可以发现,在该需求描述中隐藏着一个关键类—书籍列表,也就是执行统计的主体。

通过上面的分析,得到一个候选列表:
书籍 计算机类书籍 非计算机类书籍
借阅记录 借阅记录列表 书籍列表

3.确定类关系

可以发现“计算机书籍(itbook)”、“非计算机书籍(otheritbook)”与“书籍(book)”之间是继承关系;而“书籍列表(booklist)”是多个“书籍”组成的,“借阅记录列表(brrow list)”是由多条“借阅记录”组成的。这种组成关系使用于组合还有聚合关系呢?显然,由于本系统的“书籍”是可以独立于“书籍列表”而存在;“借阅记录”也是可以独立于“借阅记录列表”而存在,因此使用聚合更合适一些。还可以发现“借阅记录“和”“书籍”是关联的,离开“书籍”,“借阅记录”不存在意义

为了反映和记录这些类之间的关系,可以使用UML中的类图将其记录下来,如图3-22所示。

图3-22 最初的分析模型

4.给关联添加属性
(1)确定关联的多重性

例如一本书可以有几条借阅记录,书籍列表指的是多少本书籍,这些问题需要进一步的进行多重性分析,并修改上面所示的类图。
因为是个人藏书,因此每本书都是唯一的,没有副本,要么被借出,要么未被借出,因此对于每一本书籍来说,要么只有一条借阅记录,要么没有借阅记录。
所有的书籍组成书籍列表,借阅记录刘表是由所有的借阅记录组成。
通过上面的分析,可以得到信息补充的类图,即可得到如图3-23所示的类模型。

图3-23
如果系统较大,可以以上面的类图为基础,把关联度紧密的类合成一个包,以便更好的组织子系统。例如,在本例中可以将“书籍列表”、“书籍”、“计算机书籍”、"非计算机书籍“合成一个包,而将“借阅记录”、“借阅记录列表”合成另一个包。
但本例比较简单,类相对较少,因此无须进行这样的合成

(2)确定关联的导航性

类图中的诸如导航性,角色名,导出属性,限定符及约束等高级属性不是每个类模型都必须加入的。
在图3-22中,只有book和booklist之间的组合关系,brrowlrecord与borrowlist之间的组合关系、book与borrrecord之间的关联关系,这三个关系可能存在导航性。
组合关系显然已经将类的关系清晰化了,因此无须对其进行导航性描述。根据对需求的理解,book与borrowrecord之间,应该是一个双向链接。因为,当浏览书籍列表时,会希望看到某本书是否被借出;当有人归还时,希望能从借阅记录中关联到book.。

(3)确定约束

根据用户需要,我们有两个地方可以用约束来体现:一是book对象创建之后就不能被删除,只能做修改,因此在book类边上加上了一条用自由文本写的约束。二是一本书要么属于计算机类,要门属于非计算机类。因此要加一个“{xor}”约束。

(4)确定关联的限定符

由于这个系统是“个人图书管理系统”,因此特定的一本书只有一本,所以只能被借一次,因此对于一本书而言,只有一个Recordid与其对应,因此将添加一个Recordid限定符。把限定符加入图3-23中,再把类的职责(属性和方法)加入到类图后,得到的类图,如图3-24所示。

5.给类添加职责

当找到了反应问题域本质的主要类,并清理他们之间的关系之后,就可以为这些类添加相应的职责。类的职责包括以下两个内容:类所维护的信息(成员变量)和类提供的行为(成员方法)。
在本阶段将主要的成员变量和成员方法标识出来,以便更好的理解问题域。

a) 书籍类:从需求描述中,可找到书名、类别、作者、出版社;同时从统计的需要中,可得知“定价”也是一个关键的成员变量
b) 书籍列表类:书籍列表就是全部的藏书列表,其主要的成员方法是新增、修改、查询(按关键字查询)、统计(按特定时限统计册数与金额)。
c) 借阅记录类:借阅人(朋友)、借阅时间。
d) 借阅记录列表类:主要职责就是添加记录(借出)、删除记录(归还)以及打印借阅记录

通过上面的分析,我们对这些概念类有了更深入的了解,可以重新修改类,将这些信息加入原先的模型中。同时,把关联的属性加入类模型后,得到如图3-24所示的类图。
职责(属性,方法)的添加是一个循序渐进的过程,在类分析,类设计时都是逐步对类模型进行完善的。

图3-24 加入限定符和约束的类图


转载:https://blog.csdn.net/qq494370/article/details/105461968
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场