简介:
统一建模语言(UML,Unified Modeling Language)是OMG(Object Management Group)是在1997年发表图标式软件设计语言,它综合了很多种当时已经存在的面向对象的建模语言、方法和过程。对一个软件系统而言,UML语言具有以下的重要功能:可视化(Visualizing)功以、说明(Specifying)功能、建造(Constructing)功能和建文档(Documenting)功能。(本文简单介绍一下出模式设计有关知识)
UML包括什么
UML包括以下的图:
.使用案例图(Use case diagrams)
.类图(Class diagrams)
.序列图(Sequence diagrams)
.合作图(Collaboration diagrams)
.状态图(Statechart diagrams)
.活协图(Activity diagrams)
. 构件图(Component diagrams)
.部署图(Deployment diagrams)
在所有的这些图里面,案例图、类图和序列图是最为有用的。
根据这些图的用意,可以将它们大体上划分为结构型图和行为型图两种,结构型图描述了系统的静态结构,在显示一个系统已有的类及它们之间的静态关系时最为有用。行
为型图描述一上系统的动态性质,在显示系的元素如何协作产生满足要求的系统行为方面最为有用。
结构型图
行为型图
类图
在上面的类图中可以看出,表示类的框分成以下几层:
.类名
.属性清单
.方法清单
.性质清单
如果一个类有内部成员类,它的类图就会有五层。在类的类图中,除了类名层是不能省略、必须显示的以外,其他几层都是可以在UML图中省略的。
第一层是为名。类名如果是正休字,表明类是具体的(Concrete,即可以实例化的类),变量名如是斜体字,表明类是抽象的。显然在图中给出了一个具体的类。类名是不能省略、必须显示的。
第二层是属性层。一个属性可以是public、private或protected。一个属性左面如果有一个加号(+),表示它是public;一个属性的左面如果有一个减号(-),表示它是private,左面如果有一个井号(#),表示它的protected.
第三层是方法层。一个方法的左面如要有一个加号(+),表示它是public,左面如果有一个减号(-),表示它是privated;左面如果有一个井号(#),表示它是protected。
在aPublicStaticMethod()方法的下面有一道下划,表明这是一个静态的方法。
第四层是性质层。性质是由一个属性即由一个内部变量,一个赋值函数(mutator)和一个取值函数(accessor)组成的结构。
Programmer类的源代码:
public class Programmer
{
//私有属性
private double salary;
//公开属性
public long lunchHours;
//保护属性
protected float jobs;
//私有属性
private char unstable;
//私有属性
private Strin jobTitle;
//公开默认构造子
public Programmer()
{
//default constructor
}
//公开构造子
public Programmer(String jobTitle)
{
this.jobTitle=jobTitle;
}
//私有方法
private void work()
{
System.out.println("working...");
}
//私有方法
private void updateSkills()
{
//there is nothing here
}
//私有方法
private void applyForVisa()
{
//get Visa extended
}
//公开方法
public void sellBugs(String customer)
{
//sell bugs to customers
}
//公开方法
public void chargeForFixes(String customer)
{
//charge customer for fixes
}
//公开方法
public void increaseSalary(double amount)
{
this.salary+=amount
}
//公开方法
public void getJobTitle() {
return jobTitle
}
//公开方法
public void setJobTitle(String jobTitle)
{
this.jobTitle=jobTitle;
}
}
描述对象的为图
对象图是一种特殊的类图,它显示出的不是类而是类的实例。对象图在显示一小部分系统结构关系时,特别是有递归关系的结构时非常有用。
在对象图中,每一个长方形都代表一个实例。实例的名字是有下划线的。这样可以区分一个长形所代表的是类不是对象。只要图的含义是清楚的,那么对象的名字或者类的名字可以从图中省略,如下图所示。
在上面的对象图中,一共给出了六个对象,都是《红楼梦》中人物,它们的名字都带下划线。这些对象一个引用另一个,形成一个环形。
类图中的关系
在类与类之间,会有连接线指明它们之间的关系。类与类、类和接口、接口和接口之间可以建立以下几种关系:一般化关系、关联关系、聚合关系、合成关系和依赖关系,这几种关系都是静态的。
一般化关系
一般化(Generalization)关系表示类与为之间的继承关系,接口与接口之间的继承关系,或类对接口的实现关系。一般化的关系是从子类指向父类的,或从实现接的类指向被实现的接口中,与继承或实现的方向相反,如下图所示。
一般化关系在Java语言中可以直接翻译为关键字extends和implements。前者述类与类之间、接口与接口之间的般化关系,后者描述与接口之间的一般化关系。
关联关系
关联(Associaton)关系是类与类之间的联接,它使一个类知道另一个类的属性和方法。关联可以是双向的,也可以是单向的。双向的关联可以有两个箭头或者没有箭头。单向的关联有一个箭头,表示关联的方向,如下图所示,单向的关联更为普遍,通常不鼓励使用双向的关联。
在Java语言里,关联关系是使用实例变量实现的,比发在上面的Driver 类中,就出现一个类型为Car的实例变量,这个变量实现了这两个类之间的关联关系。每一个关联都有一个名字,在上面的例子里,产联的名字是Drives.
每一个关联都有两个端点,每一个端点都可以有一个角色名,显示出关联的本质。一个关联可以有一个方向箭头,表明遍历或者查询的方向。
在每一个关联的端点,还可以有一个基数(Multiplicity),表明这一端的类可以有几个实例。比哪,唐僧和他的徒弟形成一个关联关系,在这个关系里面,唐僧只能有一个而徒弟可以有好几个,如下图所示。
常见的基数有下表所示的这些
其中记号n..m表明一个取值区间,也就是n~m个实例。
一个关联关系往往可以进行步确定为聚合关系或者合成关系。比如,唐僧与他的徒弟的关系就可以进一步确定为聚合关系。
聚合关系
聚合(Aggregation)关系是关联关系的一种,是强的关联关系。聚合是整体和个体之间的关系。例如,汽车类与引擎类、轮胎类,以及其他的零件类之间的关系便是整体和个体的关系。一个汽车对象是由一个引擎对旬、四个轮胎对象组成的,如下图所示。
与关联关系一样,聚合关系也是通过实例变实现的。以上面的例子为例,Car类中应当有一个类型为Engine的属性和一个类型为Tire的数组属性。但是,关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等的层次上的,一个代表整体,另一个代表部分。
关联与聚合仅仅从Java语法上是分辨不出的,需要考察所涉及的为之间的逻辑关系。如果读者不是很确定一个关系是不是聚合关系,可以将之设置为关联关系。
合成关系
合成(Composition)关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期,合成关系是不能共享的。
代表整体的对象需要负责保持部分的对象的存活,在一些情况下负责将代表部分的对象湮灭掉。代表整体的对象可以将代表的部分的对象传递给另一个对象,由后都负责此对象的生命周期。换言之,代表部分的对象在每一个时刻只能与一个对象发生合成关系,由后者排他地负责其生命周期。聚合关系和合成关系的为图如下图所示。
在上面的类图中,显示了美猴王(MonkeyKing)以及他的四肢(Limb)和他的金箍棒(GoldRingedStaff)之间的关系。可以看出,MonkeyKing与GoldRingedStaff之间的聚合的关系;而MonkeyKing与Limb之间的关系要比前者更强,是合成关系,因为美猴王的四肢完全由美猴王自己负责,并且不能共享。
如果读者不能确定一个关系是不是合成关系,可以将之设置为聚合关系,甚至关联关系。
依赖关系
依赖(Dependency)也是类与类之间的连接,依赖总是单向的,依赖关系表示一个类依赖于另一个类的定义。一个人(Person)可以买车(Car)和房子(House),Person类依赖于Car类和House类,如下图所示。
在上面的列子里,Person类依赖于Car类和Home类的定义,因为Person类引用了Car和Home。与关联关系不同的是,Person类里并没有Car和Home类型的属性,Car和Home的实例是以参量的方式传入到buy()方法中去的。其源代码如下:
Person源代码片断:
public class Person
{
public void buy(Car car)
{
....
}
public void buy(Home house)
{
....
}
}
一般而言,依赖关系在Java语言中体现为局域变量、方法的参量,以及对静态方的调用。换言之,一个类A的某一个局域变量的类型是一个类B,那么类A就依赖于类B。如果一个方法的参量是另一个类B的实例,那么这个方法所在的类A依赖于类B。如果一个类A调用另一个类B的静态方法,那么类A依赖于类B。
如果类B出现在类A的实例变量中,那么类A与类B的关系就超越了依赖关系,而变乭某一种关联关系。
时序图
时序图有时又叫做序列图、活动序列图。作为交互图的一种,序列效互图的一种,序列交互图按照时间顺序从上往下显示每个使用案例。下图所示的便子显示了一个银行客户在ATM机器上查阅账号信息的时序图。
在一个时序图中,垂直的虚线叫做生命线,它代表一个对象存在的时间。每一个箭头都是一个调用,这个箭头从调者对象连接到接收者对象的生命线上的激活条(Activation Bar)上。每一个激活条代表调用所持续的时间。
在上面的时序图中,John向“读卡机”发出“读卡”调用,然后“读卡机”向自身发出同样的调用,然后将自身的“初始化”。从这以后,“读卡机”和“ATM屏幕”发出“提示输入密码”的调用,而后者则向John发出调用,要求输入密码。
当John输入密码完毕后,“ATM屏幕”向“John的账号”发出“打开账号”和“验证密码”的命令,成功以后,“ATM屏幕”又显示可以选的事务给John。
这时候,John选择查看账号,这一调用由John发给“ATM屏幕”的,后者将这个指令转给“John的账号”,然后执行这个指令,将账号信息伟递给“ATM屏幕”,而“ATM屏幕”则向John显示出账号的信息。
UML建模工具
工具包括如果内容:
.Rational Rose
.Together
.Microsoft Visio
.Visual UML
.Model Bridge
.MicroGold WithClass
.QuickUML