什么是UML类图

UML全称为:Unified Modeling Language,中文为:统一建模语言
,它是非专利的第三代建模和规约语言。UML是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。

上面是UML的定义,UML本身是一个挺复杂的东西,包括了:

  1. 用例图
  2. 时序图
  3. 类图
  4. 活动图
  5. 部署图
  6. 组件图等等。。。

很多,简单来说它就是使用图形来表示程序的一种方式,它主要面对的多为强类型的面向对象语言,比如说java就是一个最好的表现形式。但是对于JavaScript来说,因为它是一个弱类型的,并且没有接口,泛型这些东西(TypeScript除外),所以如果我们使用UML来表示JavaScript程序则要简单的多。

所以我们上面列举出来的UML的这些分类,我们只需要学习UML类图就可以了,下面我就看一下子,我们如何使用UML类图来表示JavaScript程序。

UML类图的基础用法

我这边是使用了一个在线的UML编译器 ProcessOn 来制作的

在这里插入图片描述

上面的类图表明了我们在本章课程中所用到的所有与类图相关的内容,整个内容还是比较简单的。 我们来一起过一下。

类(class

在这里插入图片描述

首先是类,每个这样的图形都表示为一个类,他从上到下被分为了三个部分:

  1. 第一是类名
  2. 第二是这个类的属性,其中“+”、“-”、“#”分别表示publicprivateprotected,不过在JavaScript中,不需要关注那么多的属性,我们只需要关注+ public就可以。然后 attribute1表示为属性名,type表示为属性的类型。
  3. 第三表示类中的方法。+ operation1(params):returnType从左到右分别表示为:一个公开的方法operation1它接收一个参数params,方法返回returnType
关系(relation

我们所使用到的关系比较简单,主要就是两种:

  1. 首先是继承,三角箭头为空的实线表示 “继承” , 箭头指向父类
  2. 其次是关联,比如在上面的类图中,子类持有关联类的对象,那么就表示子类与关联类建立了一个关联的关系。三角箭头不为空的实线表示 “关联” , 箭头指向被拥有者。

了解了UML类图的基础表示之后,我们通过一个事例来看一下UML类图在实例中的应用。

实例

我们通过一个事例来把UML类图熟悉一下,并通过代码把这个事例进行一个实现。

我们先来看一下项目需求

一个学校里面有三个老师,每个老师有10个学生。
有一个公告发布,并通知了学校
学校需要通知给每个老师
每个老师需要通知给他们的所有学生

就这样一个简单的需求,我们来分析一下如何去设计这个项目。

  1. 首先一个学校里面有三个老师,每个老师有10个学生,那么就表示我们需要有三个类分别表示学校、老师、学生
  2. 然后有一个公告发布,并通知了学校,表示还需要有一个公告的类,并且拥有一个发布的功能并持有学校的引用
  3. 然后学校需要通知给每个老师,表示学校在接收到公告的通知之后,需要通知学校里的三个老师
  4. 最后每个老师需要通知给他们的所有学生,在老师接到来自学校的公告之后,需要通知给所有的学生。

在分析完成之后,我们来画一下它的XML类图,大家可以先自己画一下,然后看一下再看一下和我画的有什么不同,

在这里插入图片描述

这就是我画出来的UML类图,整体还是比较简单:

  1. 首先它包含4个类,School(学校)、Teacher(教师)、Student(学生)、Notice(公告)
  2. 然后Notice持有School的引用,并拥有一个release发布的方法,该方法接收一个需要发布的消息参数msg
  3. School持有Teacher的引用teachers,它是一个数组,表示了所有的老师,并且它拥有一个接收公告的方法receive,和一个发布公告的方法release
  4. Teacher持有Student的应用students,同样为一个数组,表示了每个老师的所有学生,同样拥有一个接收公告的方法receive,和一个发布公告的方法release
  5. Student则只拥有一个接收公告的方法receive,同时每个学生拥有一个名字name方便我们验证代码的时候作为标记

大家可以先把自己所画出来的UML类图和上面的做一个对比,在UML类图被明确之后,我们就可以进行代码的开发了。

首先开发的业务逻辑代码如下:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 创建类Notice
class Notice {
// 接收一个school对象
constructor (school) {
this.school = school;
}

// 发布消息的方法,接收消息参数
release (msg) {
this.school.receive(msg);
}
}

// 创建类School
class School {
// 接收学校中的老师teachers
constructor (teachers) {
this.teachers = teachers;
}

// 接收公告
receive (msg) {
this.release(msg);
}

// 发布公告
release (msg) {
this.teachers.forEach(teacher => {
teacher.receive(msg);
});
}
}

// 创建类Teacher
class Teacher {
// 接收每个老师的学生
constructor (students) {
this.students = students;
}

// 接收公告
receive (msg) {
this.release(msg);
}

// 发布公告
release (msg) {
this.students.forEach(student => {
student.receive(msg);
});
}
}

// 创建类Student
class Student {
// 每个学生都有自己的名字
constructor (name) {
this.name = name;
}

// 接收公告
receive (msg) {
// 接收到公告之后的验证
console.log(`学生${this.name}接收到公告:${msg}`);
}
}

这就是根据UML类图做出来的业务逻辑代码,代码还是比较简单的,上面有详细的注释,我们就不在说了。

业务逻辑代码完成之后,接下来就应该是代码的验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 生成30个学生
let students = [];
for (let i = 0 ; i < 30 ; i++) {
let student = new Student(i + 1);
students.push(student);
}

// 生成3个老师
let teacher1 = new Teacher(students.splice(0, 10));
let teacher2 = new Teacher(students.splice(0, 10));
let teacher3 = new Teacher(students.splice(0, 10));

// 创建学校
let school = new School([teacher1, teacher2, teacher3]);
// 创建公告
let notice = new Notice(school);

// 发布公告
notice.release("新发布的消息");

我们可以通过一个html文件引入我们的这个js文件来验证代码。当我们调用notice.release("新发布的消息");的时候,则会打印出学生1-30接收到公告:新发布的消息.

总结

在本章我们学习了UML类图的基础使用,我是通过一个在线的UML绘制工具 ProcessOn来制作的,在介绍完了UML类图的一些基础知识点之后,我们通过一个小的实例来把我们所学到的内容进行了一个实践。

相信经过本章的学习,大家都能够掌握UML类图的这些基础知识,当然我们本课程中所使用的关于UML的内容都是最基础的东西,整个UML的知识点还是非常多的,有兴趣的同学可以多去了解一下。

本次课程之后的内容都会按照这种内容排序的方式来进行,部分非常重要的设计模式会为大家列举一些经典的使用场景,即:

  1. 理论
  2. 举例
  3. 实现
  4. 场景
  5. 总结

这样五个步骤来走。希望大家能够在后面的课程中学习愉快。