UML类图关系 --- 从模型图到代码

本文关注于利用UML框图将模型表达为代码的过程,其中穿插有设计模式。

类之间的关系

整体部分关系

整体部分类关系
整体-部分关系使用一条带菱形的线段表示。菱形侧代表整体。整体-部分关系可再细分为以下几种:

1.关联关系(Association)

关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为类B的全局变量。如学生-课程-老师的关联关系:1名学生可以选0到多门课程,每门课程对应至少1名学生;1门课程有1位授课老师,一名老师可以教授0到多门课程。双向的关联不需要用箭头。
Teacher-Cource-Students

2.聚合关系(Aggregation)

聚合关系是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即 has-a 的关系。此时,整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU、公司与员工的关系等。代码层面的表现和关联关系是一致的,只能从语义级别来区分。
比赛队和运动员的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* 聚合关系示例
*/

// 运动员
class Athelete {
private String name;
public Athelete(String _name) {
name = _name;
System.out.println("A new athelete:" + name);
}
}

// 比赛队
class Team {
private String name;
private List<Athelete> atheletes;

public Team(String _name) {
name = _name;
System.out.println("A new team:" + name);
atheletes = new List<Athelete>();
}

public addAthelete(String athelete_name) {
atheletes.add(new Athelete(athelete_name));
System.out.println("Add " + athelete_name + " into " + name);
}
}

在示例中,运动员数组对象作为比赛队类中的私有对象,使用setter方法来设置。

3.组合关系(Composition)

组合也是关联关系的一种特例,他体现的是contains-a的关系。这种关系更强,也称为强聚合。它同样体现整体与部分的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味这部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。

总的来说,几种关系所表现的强弱程度依次为:组合 > 聚合 > 关联。

关联与聚合关系的比较

  1. 从代码层面表现看,关联与聚合是一致的,只能从语义级别来区分
  2. 关联和聚合在语义上的区别在于:关联的两个对象之间一般是平等的,例如朋友关系;而聚合则一般是不平等的,如家庭-子女关系。
  3. 关联是一种结构化的关系,指一种对象和另一种对象有联系,比依赖关系要强。
  4. 关联和聚合是视问题域而定的。例如,在关心汽车的领域内,轮胎是一定要组合在汽车类中的,因为它离开了汽车就没有意义了;而在买轮胎的店铺业务里,轮胎就算离开了汽车也是有意义的,这就可以用聚合了。

一般-特殊关系

继承关系 Inheritance

Inheritance
继承关系是指子类中的成员有部分来自父类的成员,在UML类图中通常用”实线+空心三角箭头”来表示,箭头方向由子类指向父类。

1
2
3
4
5
6
7
8
9
10
11
class Person {
String name;
int sex;
public Person() {}
}

class Clerk implements Person {
int position;
double salary;
public Clerk() {}
}

继承关系在一些资料和设计软件中又被称为泛化关系(Generalization)。

实现关系

Realization
实现关系是定义的接口与实现类的关系,在UML类图中通常以“虚线+空心三角箭头”表示,箭头方向由实现类指向接口。

1
2
3
4
5
6
7
8
9
10
11
interface Tool {
String use();
}

class Car implements Tool {
public Car() {}

public String use() {
return "drive";
}
}

对象之间的消息

1
2
3
4
5
6
7
8
9
10
class Util {
public fun1() {}
public fun2() {}
}

class Call {
public callFunc() {
Util.fun1();
}
}

依赖关系

如果类A的某个方法使用到了B类,可能是方法的参数是B类,也可能是在方法中获得了一个B类对象。则A类依赖于B类。依赖关系使用虚线箭头表示。

区别依赖关系还是关联关系主要就看这个类是以成员变量的形式还是局部变量的形式存在于另一个类中的,如果是成员变量,就是关联关系;如果是局部变量,就是依赖关系。

参考文献

谈谈类之间的关联关系与依赖关系: https://www.cnblogs.com/iyangyuan/archive/2013/06/16/3138463.html

Design patterns ── Singleton Wireshark网络包分析教程

评论

You forgot to set the shortname for Disqus. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×