




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
认识UML类图元素开发Java应用程序时,开发者要想有效地利用统一建模语言(UML),必须全面理解UML元素以及这些元素如何映射到Java。本文重点讨论UML类图中的元素。类图是最常用的UML图,它用于描述系统的结构化设计。其中包括类关系以及与每个类关联的属性及行为。类图能出色地表示继承与合成关系。为了将类图作为一种高效的沟通工具使用,开发者必须理解如何将类图上出现的元素转换到Java中。下面来进一步探索这一转换过程。 元素 类(Class)类(图A)是对象的蓝图,其中包含3个组成部分。第一个是Java中定义的类名。第二个是属性(attributes)。第三个是该类提供的方法。属性和操作之前可附加一个可见性修饰符。加号(+)表示具有公共可见性。减号(-)表示私有可见性。#号表示受保护的可见性。省略这些修饰符表示具有package(包)级别的可见性。如果属性或操作具有下划线,表明它是静态的。在操作中,可同时列出它接受的参数,以及返回类型,如图A的“Java”区域所示。 Du: (+)public (#)protected ()省略 (-)private图A包(Package)包(图B)是一种常规用途的组合机制。UML中的一个包直接对应于Java中的一个包。在Java中,一个包可能含有其他包、类或者同时含有这两者。进行建模时,你通常拥有逻辑性的包,它主要用于对你的模型进行组织。你还会拥有物理性的包,它直接转换成系统中的Java包。每个包的名称对这个包进行了惟一性的标识。图B接口(Interface)接口(图C)是一系列操作的集合,它指定了一个类所提供的服务。它直接对应于Java中的一个接口类型。接口既可用图C的那个图标来表示,也可由附加了的一个标准类来表示。通常,根据接口在类图上的样子,就能知道与其他类的关系。图C类间关系后面的例子将针对某个具体目的来独立地展示各种关系。虽然语法无误,但这些例子可进一步精炼,在它们的有效范围内包括更多的语义。依赖(Dependency)实体之间一个“使用”关系暗示一个实体的规范发生变化后,可能影响依赖于它的其他实例(图D)。更具体地说,它可转换为对不在实例作用域内的一个类或对象的任何类型的引用。其中包括一个局部变量,对通过方法调用而获得的一个对象的引用(如下例所示),或者对一个类的静态方法的引用(同时不存在那个类的一个实例)。也可利用“依赖”来表示包和包之间的关系。由于包中含有类,所以你可根据那些包中的各个类之间的关系,表示出包和包的关系。图D关联(Association)实体之间的一个结构化关系表明对象是相互连接的。箭头是可选的,它用于指定导航能力。如果没有箭头,暗示是一种双向的导航能力。在Java中,关联(图E)转换为一个实例作用域的变量,就像图E的“Java”区域所展示的代码那样。可为一个关联附加其他修饰符。多重性(Multiplicity)修饰符暗示着实例之间的关系。在示范代码中,Employee可以有0个或更多的TimeCard对象。但是,每个TimeCard只从属于单独一个Employee。图E聚合(Aggregation)聚合(图F)是关联的一种形式,代表两个类之间的整体/局部关系。聚合暗示着整体在概念上处于比局部更高的一个级别,而关联暗示两个类在概念上位于相同的级别。聚合也转换成Java中的一个实例作用域变量。关联和聚合的区别纯粹是概念上的,而且严格反映在语义上。聚合还暗示着实例图中不存在回路。换言之,只能是一种单向关系。Du: human - hands图F合成(Composition)合成 (图G)是聚合的一种特殊形式,暗示“局部”在“整体”内部的生存期职责。合成也是非共享的。所以,虽然局部不一定要随整体的销毁而被销毁,但整体要么负责保持局部的存活状态,要么负责将其销毁。局部不可与其他整体共享。但是,整体可将所有权转交给另一个对象,后者随即将承担生存期职责。Employee和TimeCard的关系或许更适合表示成“合成”,而不是表示成“关联”。图G泛化(Generalization)泛化(图H)表示一个更泛化的元素和一个更具体的元素之间的关系。泛化是用于对继承进行建模的UML元素。在Java中,用extends关键字来直接表示这种关系。图H实现(Realization)实例(图I)关系指定两个实体之间的一个合同。换言之,一个实体定义一个合同,而另一个实体保证履行该合同。对Java应用程序进行建模时,实现关系可直接用implements关键字来表示。图I精确映射如本文所述,UML类图上的元素能精确映射到Java编程语言。开发团队的成员可利用这种精确性来加强沟通,取得对系统结构化设计的共识。用UML描述Java类Java程序员的角度阐述UML和对象建模问题,是一个深入浅出的实用性介绍。虽然从历史和基本理念方面来探讨UML非常吸引人,但我们还是直接从Java代码开始,看看UML如何描述Java类,再在叙述过程中插入一些历史和基本理念方面的知识。UML类图在Java中,我们用下面的代码声明两个公用类,每一个Java类放入一个文件,文件的名字就是Java类的名字加上扩展名.java:public class Personpublic class Organization UML是Unified Modeling Language的缩写,即“统一建模语言”。与Java不同,UML是一种图形化的建模“语言”,它用一个矩形来表示一个类,在矩形的内部写上类的名称,一个类图可以放入多个类。用矩形表示类,是UML中U(Unified)起的作用。在UML的第一个版本出现,每一个对象建模专家都有自己的一套符号,一些人用点表示类,一些人用圆圈表示类,还有一些人用圆角矩形表示类。显然,这很容易引起混乱。后来,Rational公司的三个专家Grady Booch、James Raumbaugh、Ivar Jacobson达成了一致意见,同意“统一”他们各自使用的符号,UML终于创立,符号之争也终于落下了帷幕。图一就是上面两个Java类的UML类图:图一 有二个类的简单类图如果要描述一系列类的内部结构以及它们相互之间的关系,UML类图是非常有用的。例如,在许多书籍中,我们可以看到作者用类图来描述各个类之间的关系。显然,空的类没有什么实际意义。我们要为Person类加上一些实例变量和简单的方法。下面是Person类的代码,已经过简化处理,不含任何注释: public class Person private String name;private String socialSecurityNumber; private Date dateOfBirth; private String emailAddress; public String getName() return name; public void setName(String name) = name; public String getSocialSecurityNumber() return socialSecurityNumber; public void setSocialSecurityNumber(String socialSecurityNumber) this.socialSecurityNumber = socialSecurityNumber; public Date getDateOfBirth() return dateOfBirth; public void setDateOfBirth(Date dateOfBirth) this.dateOfBirth = dateOfBirth; public int calcAgeInYears()/*not implemented yet*/return 0; 图二显示了Person类的UML图。可以看到,UML用“+”和“-”符号分别表示public和private修饰符。UML只显示操作和属性类型之类的特征信息,操作的结果在行未的冒号之后声明。图二 在UML类图中描述属性和方法由于UML类图不包含方法的具体实现,所以在UML类图中查看属性和方法等基本信息要比直接查看Java源代码更方便一些。在创建UML图时,人们常常忽略或隐藏各种细节信息,以便查看和掌握类的整体结构。例如,UML类图常常只显示出属性和操作的名称,简单的访问器方法(诸如getXXX()、setXXX()之类的方法)也常常不显示出来。图三就是简化图二得到的结果。图三 经过简化的Person类UML图图三清楚地显示出了Person类主要的属性和方法。但是,单个类的UML图还不是很有用。只有包含多个类且描述了多个类之间关系的UML图,才具有实用意义。UML用两个类之间的连线来表示两者之间的关系,不同的线型表示不同的关系,在UML类图中最常见的关系是关联关系。关联关系前面Person类的属性都是简单类型(Primitive Type),或者说是Java直接提供的标准类型。现在来考虑下面的代码片断,它增加了一个对Organization实例的引用:public class Person .private Organization employer; . 引用的名称是employer,意味着这里的Organization代表着Person的雇主。图四显示了如何在UML中描述这种关系: 图四 两个类之间的关联关系两个类之间的连线表示Person类对Organization类有一种依赖关系。这条线是一条实线(而不是虚线),表示这种依赖关系是一种关联。 如有必要,关联关系可显示出角色、多重性、关联方向等属性。图四的关联关系显示出Organization对象在该关系中是雇主的角色,“0.1”表示每一个Person类的对象最多和一个Organization类的对象有关系,也可能和0个Organization对象有关系(即Person对Organization的引用可设置为null)。开叉的箭头表示Person类拥有对Organization的引用,而不是Organization拥有对Person的引用。多重性多重性回答这样一个问题:在一个关系中,每个类各有多少对象参与其中?常见的多重性如图五所示。图五 常见的多重性及其含义前面我们已经看到了Java代码中0.1多重性的实例。不难猜测,多重性为“1”意味着一个类对另一个类的引用不能为null(一般是这样一种情形:引用的值在构造函数中初始化,且在所有相关的set方法中禁止把该引用设置为null)。值为“1.*”和“0.*”的多重性稍微复杂一点。在Java中,实现这类多重性的途径之一是使用某种集合类,例如Vector,来保存可能需要用到的多个引用:多重性回答这样一个问题:在一个关系中,每个类各有多少对象参与其中?常见的多重性如图五所示。前面我们已经看到了Java代码中0.1多重性的实例。不难猜测,多重性为“1”意味着一个类对另一个类的引用不能为null(一般是这样一种情形:引用的值在构造函数中初始化,且在所有相关的set方法中禁止把该引用设置为null)。值为“1.*”和“0.*”的多重性稍微复杂一点。在Java中,实现这类多重性的途径之一是使用某种集合类,例如Vector,来保存可能需要用到的多个引用: ClassA. Vector classB; / 保存B类对象引用的Vector . 对于“1.*”多重性,Java程序必须确保Vector至少包含一项内容。在有些关系中,多重性的值可以是某个精确的范围或数字。例如,一个小孩最多有两个生物学意义上的健在双亲,即它的多重性可表示为“0.2”。用Java代码描述这种关系时,程序必须带有确保Parent对象实例少于或等于2个的约束。一个UML关联加上多重性、角色、关联方向之后,能够描述出大量信息,远比一大堆Java源代码简洁和直观。虽然UML图没有说明关系的具体实现方式,但它能够充分地说明关系的意义和作用。图六显示了标注多重性、角色名称之后的雇佣关系,它表示一个Person可以为多个Organization工作,一个Organization可以雇佣多个Person。图六 双向关联关系聚合与合成关联只是UML中的关系之一。下面我们来看看UML中的其他两种关系聚合(Aggregation)和合成(Composition),它们实际上是关联关系的不同变种。聚合是这样一种关联关系,在这种关系中一个类的对象代表着另一个类的对象的一部分,有的人因此也把聚合关系叫做“全体-部分”关系。聚合关系用实线空心菱形箭头表示,箭头由表示Part的类指向表示Whole的类,参见图七。图七 聚合与合成那么,在Java程序中聚合关系又是什么样的呢?答案是:这要看你在问谁。聚合是一个有争议的概念,表达的是一种生命周期依赖关系。有人根据习惯认为,聚合意味着Whole类必须负责创建和拆除Part类的对象;但也有人为聚合关系下了更宽松的定义。到底应该怎么理解,你最好能够在合作者之间取得一致意见和约定,避免混淆。合成是一种较强的聚合关系。这两种关系基本相似,不同之处在于,在合成关系中,Part的对象任何时候只能从属于一个Whole对象,也就是说,必须用Java代码确保这种唯一的从属关系。前面我们已经看到,类的属性、操作以及各个类之间的关系可以用UML类图来描述。然而,对于Java类里面的对象引用,什么时候应该把它当作关联关系、什么时候把它当作属性,这一点还没有搞清楚。答案是:要在哪一个层次交流信息,UML图就应该具体到哪一个层次。有些时候,即使是简单的对象,也最好画出它的类图,把其他类对它的引用描述成关联关系;另一些时候,可能需要把对象引用表示成属性,甚至从类图完全省略对该对象的引用,以便在类图中突出显示其他更重要的类和关系。大多数的UML工具软件都提供了隐藏UML类图各种细节信息的机制。获得UML图一般有两种办法,手工设计UML图(在此基础上可由UML工具生成Java应用的骨架代码),或者用工具分析Java源代码(甚至字节码)获得UML图。一些优秀的UML工具能够在你绘制UML图的同时生成Java代码,在你编辑Java代码的同时更新UML图。例如TogetherSoft的Together ControlCentre,本文的UML图就是用这个工具绘制的,有免费版Together Community Edition可供试用。Java与UML交互图本文讨论的是一种UML图交互图(Interaction Diagram)。交互图描述的是一组对象之间的交互过程,或者说,这里我们实际上要回答这样一个问题:“方法调用过程在UML中怎样表示?”UML交互图本文将通过一个非常简单的交易系统来说明UML交互图。这个系统包含六个Java类。从前面几篇文章中,我们已经知道UML类图是分析Java程序结构(静态结构)的有效方法,图一显示了这个交易和支付系统的类图。为了更清楚地说明各个类的职能和角色,图一利用了前面介绍过的彩色类原型表示法。图一 一个简单交易系统的UML类图如果我们跟踪任意一个Java程序的执行过程,就会发现,这个过程包含了一个或者多个对类和对象的方法调用。我们通过调用对象的方法来寻求特定问题的答案或执行一个特定的动作。很多时候,被调用的方法还会调用其他方法或者是同一对象的方法,或者是同一类的其他对象的方法,或者是其他类的对象的方法。类似地,这些被调用的方法又会继续调用其他方法,直至问题得到了明确的答案或动作全部执行完毕(或者出现异常,这时问题将没有答案或动作不能完成)。UML交互图以图形的形式表示出方法调用过程,它有两种形式:序列图(Sequence Diagram)和协作图(Collaboration Diagram)。序列图要达到某个特定的目标,必然要执行一系列的方法调用。UML序列图的典型用途就是显示出方法调用过程。图二显示了一个交易事务中计算累计金额的序列图,调用从Sale类的calcTotal()方法开始,相关的代码片断在序列图之后给出。术语说明:UML把操作(Operation)定义为方法的特征(Signature)。“方法”(Method)这一术语被保留给实现操作的代码。但在Java环境中,“方法”这一术语的应用范围更广泛一些。在UML序列图中,调用一个操作就叫做发送一个消息(Message)。序列图实际上阐述了操作的具体实现,所以下面我们会较多地用到“方法”这个术语(偶尔也会用到“消息”这个术语)。图二 计算交易总金额的序列图 /* 属于Sale类:* 从lineItem的单项金额计算交易总金额 * return 交易总额 */ public double calcTotal() total = 0.0; Iterator i = lineItems.iterator(); while (i.hasNext() total += (LineItem)i.next().calcTotal(); return total; /* 属于LineItem类:* 计算当前项目的交易金额* return 交易金额 */public double calcTotal() total = product.calcTotal(this); return total; /* 属于Product类:* 计算指定数量的产品价值多少 * return 金额*/public double calcTotal(LineItem li) return amount * li.getQuantity(); 为了便于把握序列图的总体情况,图一只显示了方法的名称。详细的序列图可以显示出方法的参数和返回值。在序列图中,对象以常规的UML符号显示,即使用与对象所属的类一样的形状或符号(默认是矩形),再注明对象的名称,加上一个冒号(对象的表示方式),再加上相应的类名称。然后再为整个名字加上下划线(例如,图二中的aProduct:Product)。可以省略对象的名字(例如图二中的:Sale),也可以省略类的名字(例如图二的Sender),但两者都省略显然是不允许的。如果省略了类的名字,冒号必须保留。时间的流逝方向是从上到下的垂直方向。每一个对象有一条顺着页面垂直向下的生命线(Lifeline),紧接着表示对象的矩形。方法调用的表示方式是,画一根从发出调用的对象的生命线指向被调用对象生命线的箭头。只要对象的任意方法处于执行状态,对象的生命线加宽。加宽之后的生命线称为“活动条”(Activation Bar),活动条可以嵌套,表示在前一方法的执行过程中,又有同一对象的另一个方法被调用,图二的getQuantity()方法示范了活动条嵌套的一个例子。方法的返回值可以通过虚线开叉箭头的形式表示,但这是可选的,例如图二中从:Sale指向Sender的箭头。如果要在一个对象的集合上进行迭代操作,则在方法的名字前面加上一个星号(再在方括号里面说明循环条件,可选)。在图二中,Sale类对LineItem类对象的调用给出了迭代操作的一个例子。就象UML类图一样,原本需要查看多个源代码文件才能了解的信息,通过一个UML序列图就可以表示出来。对已有的代码实施反向工程获得对应的序列图,可以帮助不熟悉代码的开发者快速了解程序的工作流程。图三显示了Sale类complete()方法的序列图,它对调用次序(消息)进行了编号。complete()方法调用了Sale类的另外两个方法,即calcTotal()和calcPayments()。图三用环形的回调符号表示一个对象正在调用它自身的方法。图三 完成一次交易的序列图如果序列图很大,可能出现一个屏幕无法显示出来的情况。在图三中,通过设置建模工具Together ControlCenter的选项面板,类的名称不再和对象名称并列显示,而是显示在对象名称的下方,减少了显示对象所需的水平空间。如果类的名称很长,用这种显示方式可以有效地缩减图形宽度,一般能够改善图形的可读性。然而,如果要严格遵从最新的UML规范,类的名称必须和对象名称并列放置,中间用冒号分隔,如图二所示。complete(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年安全员竞聘安全服务题及答案
- 2025年BIM安全管理体系建设题及答案
- 2025年建筑施工企业三类人员-B-证笔试预测题
- 2025年安全生产管理模拟题答案解析
- 2025年维修工笔试高频题库与解析
- 2025年视距内无人机面试必考题
- 2025年文物保护师初级考试题集
- 课件中时间轴
- 2025年健身教练从业资格水平考核试题及答案解析
- 2025年建筑材料工程师专业知识考核试题及答案解析
- 地理与劳动教育
- 第5课 甲午中日战争与列强瓜分中国狂潮 公开课一等奖创新教学设计
- 初中数学新人教版七年级上册第二章《有理数的运算》教案(2024秋)
- 人教版(2025新版)七年级下册数学第七章 相交线与平行线 单元测试卷(含答案)
- 厂房消防应急预案
- 景区开发政府战略框架协议书(2篇)
- “雄鹰杯”全国小动物医师技能大赛考试题库(660题)
- 实验室隐患排查培训
- 九年级化学第三单元课题1分子和原子人教新课标版省公开课获奖课件说课比赛一等奖课件
- 宠物医疗器械创新与发展
- 4《给植物画张“像”》教学设计-2024-2025学年科学一年级上册教科版
评论
0/150
提交评论