UML 类图之间的关系
现在必须使用UML图表示了,因此从网上整理了一些资料加上总结。
本篇文章也算作转载的吧。
对象图(ObjectDiagram)描述的是参与交互的各个对象在交互过程中某一时刻的状态。对象图可以被看作是类图在某一时刻的实例。
在UML中,对象图使用的是与类图相同的符号和关系,因为对象就是类的实例。
类图和UML对象图的区别
UML类图和UML对象图(对象是类的实例,那么对象图就是类图的一个实例,类图类名下面无下划线,而对象图是有的):
一、依赖关系(Dependence):假设A类的变化引起了B类的变化,则说名B类依赖于A类。
依赖关系有如下三种情况:
1、A类是B类的一个成员变量;
2、A类是B类方法当中的一个参数;
3、A类向B类发送消息,从而影响B类发生变化;
使用带箭头的虚线表示
二、泛化关系(Generalization):UML对象图和类图的泛化关系A是B和C的父类,B,C具有公共类(父类)A,说明A是B,C的一般化(概括,也称泛化)
在UML当中,对泛化关系有三个要求:
1、子类与父类应该完全一致,父类所具有的属性、操作,子类应该都有;
2、子类中除了与父类一致的信息以外,还包括额外的信息;
3、可以使用父类的实例的地方,也可以使用子类的实例;
使用带空心三角形的实线表示
三、关联关系(Association):类之间的联系,如篮球队员与球队之间的关联(下图所示)。其中,关联两边的"employee"和“employer”标示了两者之间的关系,而数字表示两者的关系的限制,是关联两者之间的多重性。通常有“*”(表示所有,不限),“1”(表示有且仅有一个),“0...”(表示0个或者多个),“0,1”(表示0个或者一个),“n...m”(表示n到m个都可以),“m...*”(表示至少m个)。
在关联中有一种叫“限定关联”,还有一种谓之自身关联。另外,对象之间的关联就没那么复杂,只是将类的关联实例化而已。
使用带数字的实线表示
四、聚合关系(Aggregation):UML对象图和类图的聚合关系表示的是整体和部分的关系,整体与部分可以分开
如:电话机包括一个话筒
电脑包括键盘、显示器,一台电脑可以和多个键盘、多个显示器搭配,确定键盘和显示器是可以和主机分开的,主机可以选择其他的键盘、显示器组成电脑;
使用带空心菱形的实线来表示
五、组合关系(Composition):UML对象图和类图的组合关系也是整体与部分的关系,但是整体与部分不可以分开
如:公司和部门,部门是部分,公司是整体,公司A的财务部不可能和公司B的财务部对换,就是说,公司A不能和自己的财务部分开;人与人的心脏
使用带实心菱形的实线来表示
六、实现关系(Implementation):是用来规定接口和实线接口的类或者构建结构的关系,接口是操作的集合,而这些操作就用于规定类或者构建的一种服务。
使用带空心三角形的虚线表示
UML(The Unified Modeling Language)就是统一建模语言,不论它是怎么发展来的,也不论最新的官方Specification或工业标准是哪个版本,我想总结一下工作中最常用的一些知识:用UML语言描述类的关系。
1,关联关系(Association)
关联关系是类(也可以说是对象)之间特定的对应关系。按照对象的数量对比,可以分为:
A 一对一
比如公民和公民身份卡之间的对应关系。
B 一对多
一个部门对应0或者多位员工,一般而言一位员工只能属于某一个部门。
C 多对多
用户和服务是多对多的关系,一个用户可以注册0个或多个服务,一个服务则可以被0个或者多个用户复用。比如Windows Live用户可以激活邮件服务、Space服务等,而这些服务不是被一个用户所专有的。
关联的实质
从A类型到B类型的关联是指在A类型中定义了B类型作为属性。如下列代码:
package uml;
public class Citizen {
private CitizenshipCard card;
//其他属性
public CitizenshipCard getCard() {
return card;
}
public void setCard(CitizenshipCard card) {
this.card = card;
}
}
上述代码演示了从Citizen 到 CitizenshipCard 的关联。注意下图箭头方向:
同样可以建立CitizenshipCard 到 Citizen 的关联:
代码表示为:
package uml;
public class CitizenshipCard {
private Citizen citizen;
//其他属性
public Citizen getCitizen() {
return citizen;
}
public void setCitizen(Citizen citizen) {
this.citizen = citizen;
}
}
如果仅仅建立从Citizen 到 CitizenshipCard 的关联或者仅仅建立CitizenshipCard 到 Citizen 的关联,都属于单向关联,如果两个方向的关联都建立,就是双向关联:
是否建立双向关联要在实际项目中酌情而定。再看个双向关联的例子:
Department -----------------------------
package uml;
import java.util.Set;
public class Department {
private String name;
private Set<Employee> employees;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
}
Employee --------------------------------
package uml;
public class Employee {
private String name;
private long joinTime;
private Department department;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getJoinTime() {
return joinTime;
}
public void setJoinTime(long joinTime) {
this.joinTime = joinTime;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
UML如何描述类之间的关系(二)
2,聚集关系(Aggregation)
聚集者和被聚集者之间是一种灵活的 平台分享关系。一个类提供平台,把另外一个类集成过来,如下图BankService将其他Services集成进来,统一为客户提供风格一致的服务。我 们面对银行的一个普通柜台工作人员,可以存取款项,可以委托理财,可以查询账户余额,可以委托代交电费,还可以挂失或销户,这些服务都是在一个地点由同一 个用户服务接口(BankService)完成的。类似的例子还有计算机和外设之间的关系:计算机可以聚集U盘、扫描仪、打印机、手机等硬件,统一为用户 提供服务,这种服务大大丰富了计算机本身的功能,也便于用户统一使用。
ATM也是一种BankService实例,我们面对ATM,也可以享受多种自助服务(温馨提示:当然,要冒着被终身监禁的风险,呵呵)。
3, 构成关系(Composition)
构成关系也是一种平台分享关系,但是这种平台是垄断的、强制的。如身体和头之间是一种构成关系,头只能在身体上,离开这个平台,就没有继续存在的机会了。
构成关系有两层含义:1,整体(父元素)和部分(子元素)之间的关系;2,部分(子元素)的生命周期隶属于整体(父元素)的生命周期,父元素消亡,子元素级联消亡。
如何区分关联关系、聚集关系和构成关系?
关联关系、聚集关系和构成关系,都属于广义的关联关系,三种关系的在面向对象的编程语言中表现方式是一致的(参考:1,关联关系 关联的实质)。但是它们的本质区别是存在的:
实质 元素生命周期 举例
关联关系 所属关系 彼此独立 用户与订单
聚集关系 灵活平台分享 彼此独立 主板与内存条
构成关系 强制平台分享 “国破家亡” 身体和脑袋;脑袋和耳朵
UML如何描述类之间的关系(三)
接着我介绍一下依赖、泛化和实现关系。
4,依赖关系(Dependency)
对象管理组织(OMG)在其最新的UML规范(V 2.1.1 2007-02-05)上是这么描述依赖关系的:
依赖关系是指一个单独的或者一组的模型元素从规范或者实现的角度,需要其他的模型元素的存在。完整的含义是:依赖方(客户方、需求方)的元素要么从语义层面,要么从结构层面,依赖供应方元素(有时不仅是一个)的定义。(7.3.12 Dependency, Page 62)
这就是“规范说明”,为了支持对各种实现者的指导,它坚持自己的抽象风格,从而不太方便人们的理解。
简单而言,依赖关系是一种局部使用关系。A类使用B类,则说明A类依赖于B类,图示如下:
A类在两种情况下使用B类:
1,A类负责构造B类的实例,即A类使用B类的构造器
【图示】
【代码】
package uml;
public class CarFactory {
public Car makeNewCar(){
return new Car();
}
}
2,A类使用B类实例的其他方法或者属性
【图示】
【代码】
package uml;
public class Person {
public void drive2Office(Car myCar){
myCar.run();
}
}
5,泛化关系(Generalization)
泛化就是一般化、概括或总结。父类是对子类的泛化,另一方面看,子类是对父类的继承。
6,实现关系(Realization)
一般是指接口与其实现类的关系。