UML如何描述类之间的关系
UML 中类之间的关系
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 的关联或者仅仅建立CitizenshipCar d 到 Citizen 的关联,都属于单向关联,如果两个方向的关联都建立,就是双向关联:
是否建立双向关联要在实际项目中酌情而定。再看个双向关联的例子:
Department ----------------------------------------------------------------- package uml; import java.util.Set; public class Department {
private String name;
private Set employees;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Set getEmployees() { return employees; }
public void setEmployees(Set 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; }
}
2,聚集关系(Aggregation)
聚集者和被聚集者之间是一种灵活的平台分享关系。一个类提供平台,把另外一个类集成过来,如下图BankService 将其他Services 集成进来,统一为客户提供风格一致的服务。我们面对银行的一个普通柜台工作人员,可以存取款项,可以委托理财,可以查询账户余额,可以委托代交电费,还可以挂失或销户,这些服务都是在一个地点由同一个用户服务接口(BankService )完成的。类似的例子还有计算机和外设之间的关系:计算机可以聚集U 盘、扫描仪、打印机、手机等硬件,统一为用户提供服务,这种服务大大丰富了计算机本身的功能,也便于用户统一使用。
ATM 也是一种BankService 实例,我们面对ATM ,也可以享受多种自助服务。 3, 构成关系(Composition)
构成关系也是一种平台分享关系,但是这种平台是垄断的、强制的。如身体和头之间是一种构成关系,头只能在身体上,离开这个平台,就没有继续存在的机会了。
构成关系有两层含义:1,整体(父元素)和部分(子元素)之间的关系;2,部分(子元素)的生命周期隶属于整体(父元素)的生命周期,父元素消亡,子元素级联消亡。
4,依赖关系(Dependency)
对象管理组织(OMG )在其最新的UML 规范(V 2.1.1 2007-02-05)上是这么描述依赖关系的:
依赖关系是指一个单独的或者一组的模型元素从规范或者实现的角度,需要其他的模型元素的存在。完整的含义是:依赖方(客户方、需求方)的元素要么从语义层面,要么从结构层面,依赖供应方元素(有时不仅是一个)的定义这就是“规范说明”,为了支持对各种实现者的指导,它坚持自己的抽象风格,从而不太方便人们的理解。
简单而言,依赖关系是一种局部使用关系。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)
一般是指接口与其实现类的关系。