概念
Class diagram is UML structure diagram which shows structure of the designed system at the level of classes and interfaces, shows their features, constraints and relationships - associations, generalizations, dependencies, etc.
类图是用于描述类、接口这一层次的图形,他表达了类、接口的功能、约束以及他们之间的关系。
使用场景
类图是适用于面向对象进行建模的场景,通过类图,我们能够知道我们对系统被抽象成了哪些类,以及他们之间的关系。因此,类图适用于使用面向对象的方法进行设计的系统、应用。
对于后端来说,一般类图常用于单一的系统内,对于微服务这类分布式架构的表达,更适用于组件图或者部署图。 对于前端来说,由于 js 的语言特性,以及react、vue 这类组件化框架大行其道,简单的业务场景就不需要使用到类图了,基于面向对象建模反而是过度设计,此时用组件图表达即可。但是当业务复杂到到一定程度,不得不使用面向对象对业务层进行建模时,类图就有意义了。
类图元素
类(class)
类是面向对象的概念,是描述一系列对象共有的功能和约束 对于类来说,功能即类的属性以及方法,约束即属性及方法的可见性。
接口(interface)
接口描述的是功能的合集,一般我们会对功能进行分类,同一类别的功能统一放在一个接口里,用接口来描述功能的抽象,以此来增强接口的可复用性。 比如 cloneable 接口,表述实现了这个接口的类是支持 clone 相关的行为的。接口和类最大的不同在于接口只描述行为,表达的是能力,比如 cloneable 接口,表达的是 clone 的能力,具体怎么 clone (如何实现)是在类的范畴,因此接口的抽象程度更高。
因为接口是一个高度的抽象,因此接口需要有实际的载体,也就是类,所以接口是需要配合类来一起表达才能有实际的含义,因此声明了接口后,还需要表明谁来实现,或者相关的依赖。
类图关系
类的基本元素比较简单,难点在于关系的表达。业务之所以复杂,不是因为业务中可以抽象出多个类,而是类之间的关系,每个类的变动都可能牵扯到其他部分,业务行为正是通过这些”牵扯“组成的。因此我们使用面向对象建模,核心的目的在于让关系变得简单,简单意味着可控,业务行为便可预测。
本章节不会把所有的关系全部说清楚,只会讲到平时开发过程中常见的 5 种关系线,他们的含义以及用法。
依赖(dependency)
两个对象间最弱的关系,表示一个类的某些行为与另一个类有相关性。 敲黑板!依赖关系是行为之间产生关联
A 依赖 B 的三种场景:
class A {function fn(B b) { }function fn2() {B b = new B()}function fn3() {return new B()}
}
泛化(generalization)
通常指一个类(或接口)继承另一个类(或接口),并可以增加它自己的新功能的能力。
A 继承类 B 实现 IC 接口:
class A extends B implements IC { }
关联(association)
二元关系,表示对象与对象之间有持有关系
单向关联关系,A 关联 B :
class A {B b
}
class B { }
双向关联关系,A 与 B 互相关联:
class A {B b
}
class B {A a
}
聚合(aggression)
含义更明确的单向关联关系,表示群体与个体的关系。群体解散了,个体可能还会存活。 聚合关系强调了对象间生命周期的关系,聚合的对象是有各自独立的生命周期的。
class A {B bconstructor(B _b) {this.b = _b}setB(B b) {this.b = b}
}
组合(composition)
和聚合关系类似,属于更明确的关联关系,表示全体和局部的关系。全体不存在了,局部也不存在了(或没有意义了),和聚合的区别在于声明周期的不同。
class A {B bconstructor() {this.b = new B()}
}
小结
我们讲的 5 种关系,都属于二元关系,区别在于使用的时机与生命周期的不同。依赖与关联的区别在于依赖仅是在行为上会使用到另一个类,而关联则是需要持有对象,会影响对象的生命周期。 聚合与组合是提出了更明确含义的关联关系,区别在于聚合的对象,生命周期是各自独立的,组合的对象,生命周期跟随整体。
要注意的是,关系是对现实事务的表达,因此关系本身也是有语义的。为了方便理解,我们使用对象声明周期的影响来区分依赖与关联,聚合与组合,但是这个只是充分非必要条件,不能狭隘的通过生命周期来反推关系
总结
- UML的类图是从程序逻辑层面上来表达系统设计的方法
- 类图是一种静态图,描述的是系统的静态结构
- 依赖关系,表达的是基于对象行为上的关联
- 关联关系,表达的是对象间的持有关系,影响对象的生命周期
- 聚合关系表达的是群体和个体的关系,删除了群体,可能不影响个体的生命周期
- 组合关系表达的是整体和局部的关系,删除了整体,局部随之消亡
思考题
- 企业与员工是什么关系?
- 企业与个人是什么关系?
- 工厂类与被生成的类是什么关系?如果是支持缓存的工厂类呢?ML