这一节我们主要讲解基础的UML类图,这个东西非常重要,是我们用来表述,认识,理解模式的关键方法,在实际工作中与其他工程师交流也可以使用UML类图。
UML类图的作用是描述程序中类的信息及各个类之间的关系。
面向对象的设计语言都离不开类这个概念,如何设计类以及如何处理类和类之间的关系是重点内容。UML类图就是一种可以帮助我们解决这方面的工具。
在UML类图中,我们通过一个矩形来表示一个类,一般的类图分为三个部分。
第一部分为类名,如果类名用正体书写则说明这是可以实例化的普通类。如果类名用斜体书写,则说明这是抽象类。如果类名有下划线修饰则说明这是静态类。
第二部分为类内的属性,格式为修饰符 属性名 :属性类型。修饰符为“+”说明该属性为public型,“#”说明该属性为protected型,“-”说明该属性为private型。
第三部分为类内的方法,格式为修饰符 方法名 (参数名1:参数类型1,……):方法返回值类型。修饰符为“+”说明该方法为public型,“#”说明该方法为protected型,“-”说明该方法为private型。如果方法名有下划线修饰则说明这是静态方法。
我来看一个具体例子 (画uml类图可以使用这个链接 画UML类图 注册一下,就可以方便使用了)
这就是一个普通的People类,里面有俩个公开属性name age一个私有属性weight 还有一个公开方法speak.
看一下代码如何表示这个类。(TS)
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1class Person {
2 public name
3 public age
4 private weight
5 constructor(name, age, weight) {
6 this.name = name;
7 this.age = age;
8 this.weight = weight;
9 }
10 speak() {
11 console.log(`I am ${this.name}, ${this.age} years old.`)
12 }
13}
14
我们可以用上面的类图来表示下面这个类,在类比较多 关系比较复杂时,看类图比代码要好很多。
有了上面的类表示方法,下面我们就可以研究类与类之间的关系了,这部分是重点内容。
类与类的关系有六种:关联,聚合,组合,依赖,实现,泛化。
虽然有六种,但是这里我们重点还是需要和JS语言结合在一起,所有我们这里介绍俩种非常重要的关系:关联和泛化。后面我会附上一篇博客,讲解六种关系的博客。
关联:简单的讲就是一个类里面包含另一个类的变量。
1
2
3
4
5
6
7
8
9
10
11 1class A{
2 constructor (B) {
3 this.b = B;
4 }
5}
6class B{
7
8}
9const b = new B();
10const a = new A(b);
11
类A里面有一个类B的变量,这就是一个关联。在UML类图中用表示
泛化:就是继承关系。
1
2
3
4
5
6
7
8
9
10
11
12
13 1class Person {
2 constructor(name, age) {
3 this.name = name;
4 this.age = age;
5 }
6}
7class Student extends Person {
8 constructor(name, age, grade) {
9 super(name, age);
10 this.grade = grade;
11 }
12}
13
Student类继承于Person类。在UML类图中用表示。
下面我使用上面俩种关系写一个复杂一点的代码并且画出UML图。(JS,因为修饰符不是重点,所有没有使用TS)
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 1class People {
2 constructor(name, house) {
3 this.name = name;
4 this.house = house;
5 }
6 speak() {
7 console.log(`hello! I live in ${this.house.getCity()}`)
8 }
9}
10class House{
11 constructor(city) {
12 this.city = city;
13 }
14 getCity() {
15 return this.city;
16 }
17}
18class Student extends People {
19 constructor(name, house, grade) {
20 super(name, house);
21 this.grade = grade;
22 }
23 work(subject) {
24 console.log(`${subject}真好玩。`)
25 }
26}
27class Programmer extends People {
28 constructor(name, house, lang) {
29 super(name, house);
30 this.lang = lang;
31 }
32 work() {
33 console.log(`${this.lang}真好玩。`)
34 }
35}
36
37const house = new House("北京");
38const s = new Student("小明", house, "A-3");
39const p = new Programmer("小王", house, "JavaScript");
40
41s.speak();
42s.work("高数");
43p.work();
44
45
People类:俩个公开属性name(Sting) house(House) 一个公开方法speak() People类关联House类 因为People类里面有一个House类的实例。
House类:有一个公开属性city(String) 一个公开方法getCity()
Student类:继承于People类,自己还有一个公开属性grade(String) 一个公开方法work.
Programmer类:继承于People类,自己有一个公开属性lang(String) 一个公开方法work.
这样看起来,代码是比较复杂的,因为涉及到四个类。假如你看代码的话,需要画一些时间来理清关系,但是如果画出类图得话,就变得非常简单了。
怎么样,是不是一目了然,各个类之间得关系十分清楚,我们看起来也非常干净,直观。
我们学习这个东西是十分有必要的,当关系复杂,类比较多时,画UML类图会帮助我们设计。
后面所讲的每一个设计模式,我都会画UML类图帮助大家理解。