模式与UML

173 阅读9分钟

模式

模式化的过程是把问题抽象化,在忽略掉不重要的细节后,发现问题的一般性本质,并找到普遍适用的解决方案的过程。

UML

统一建模语言(Unified Modeling Language,UML)是用来设计软件的可视化建模语言。同时 UML 也是一种用于软件系统分析和设计的语言工具,用于帮助软件开发人员进行思考和记录思路的结果;

UML本身是一套符号的规定,就像数学符号和化学符号一样,这些符号用于描绘软件模型中各个元素和它们之间的关系。

UML 从目标系统的不同角度出发,定义了用例图、类图、对象图、状态图、活动图、时序图、协作图、构件图、部署图等 9 种图。

根据这些图的用意,可以将它们大体上划分为结构型图行为型图两种。结构型图描述了系统的静态结构,在显示一个系统已有的类及它们之间的静态关系时最为有用。行为型图描述一个系统的动态性质,在显示系统的元素如何协作产生满足要求的系统行为方面最为有用。

结构型图

图的名字介绍
类图(Class Diagram)类图描述一些类、包的静态结构和它们之间的静态关系
对象图(Object Diagram)对象图给出一个系统中的对象的快照
构件图(Component Diagram)描述可以部署的软件构建(比如 jar 文件)之间的静态关系
部署图(Deployment Diagram)描述一个系统的拓扑结构

显然,要描述一个设计模式的静态结构,使用类图对象图就很合适。

行为型图

图的名字介绍
用例图(Use Case Diagram)用例图描述一系列的角色和用例之间的关系。可以用来对一个系统的最基本的行为进行建模
活动图(Activity Diagram)描述不同过程之间的动态接触。活动图是用例图所描述的行为的具体化
状态图(State Diagram)描述一系列对象的内部状态及状态的变化和转移。注意一个类不能有两个不同的状态图
时序图(Sequence Diagram)时序图是一种相互作用图,描述不同对象之间信息传递的时序
协作图(Collaboration Diagram)协作图是一种相互作用图,描述发出信息、接收信息的一系列对象的组织结构

显然,要描述一个设计模式的行为特性,使用状态图时序图就很合适。

只要有意义,所有类型的 UML 图都是可以混合在一起使用的。比如,一个对象图可以与一个类图同时出现在一个结构图中,一个构件图中可以有类图出现等(但一些 UML 建模工具软件不一定允许这样做)。

类图

描述系统中的类(对象)本身的组成与类(对象)之间的各种静态关系; 类之间的关系:实现、泛化(类似继承)、依赖(类似引用)、关联(包含组合、聚合)

表示法

在 UML 类图中,类使用包含类名、属性 (field) 和方法 (method) 且带有分割线的矩形来表示,比如下图表示一个 Employee 类,它包含 name,age 和 address 这3个属性,以及 work() 方法。

image.png

属性/方法名称前加的加号和减号表示了这个属性/方法的可见性,UML类图中表示可见性的符号有三种:

+:表示 public

-:表示 private

#:表示 protected

属性的完整表示方式是: 可见性 名称:类型 [ = 缺省值]

方法的完整表示方式是: 可见性 名称(参数列表) [ : 返回类型]

注意:

  1. 中括号中的内容表示是可选的;
  2. 也有将类型放在变量名前面,返回值类型放在方法名前面;
  3. 属性/方法名前面没有符号,表示这种可见性为default类型;

表示方式

关联关系

关联关系是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系,如老师和学生、师傅和徒弟、丈夫和妻子等。关联关系是类与类之间最常用的一种关系,分为一般关联关系、聚合关系和组合关系。

单向关联

image.png

在UML类图中单向关联用一个带箭头的实线表示。上图表示每个顾客都有一个地址,这通过让 Customer 类持有一个类型为 Address 的成员变量类实现。

双向关联

image.png

在 UML 类图中,双向关联用一个不带箭头的直线表示。上图中在 Customer 类中维护一个 List<Product>,表示一个顾客可以购买多个商品;在 Product 类中维护一个Customer类型的成员变量表示这个产品被哪个顾客所购买。所谓的双向关联就是双方各自持有对方类型的成员变量。

自关联

image.png

自关联在 UML 类图中用一个带有箭头且指向自身的线表示。上图的意思就是 Node 类包含类型为 Node 的成员变量,也就是“自己包含自己”。

基数

在每一个关联的端点,还可以有一个基数,表明这一端的类可以有几个实例。

常见的基数有下表所示的这些。

基数含义
0..1零个或者一个实例
0..* 或者 *对实例的数目没有限制(可以是0)
1只有一个实例
1..*至少有一个实例

其中,记号 n..m 表明一个取值区间,也就是 n~m 个实例。

聚合关系

聚合关系是关联关系的一种,是强关联关系,是整体和部分之间的关系。

聚合关系也是通过成员对象来实现的,其中成员对象是整体对象的一部分,但是成员对象可以脱离整体对象而独立存在。例如,学校与老师的关系,学校包含老师,但如果学校停办了,老师依然存在。

在 UML 类图中,聚合关系可以用带空心菱形的实线来表示,菱形指向整体。下图所示是大学和教师的关系图:

image.png

组合关系

组合表示类之间的整体与部分的关系,但它是一种更强烈的聚合关系。

在组合关系中,整体对象可以控制部分对象的生命周期,一旦整体对象不存在,部分对象也将不存在,部分对象不能脱离整体对象而存在。组合关系是不能共享的。例如,头和嘴的关系,没有了头,嘴也就不存在了。

在 UML 类图中,组合关系用带实心菱形的实线来表示,菱形指向整体。下图所示是头和嘴的关系图:

image.png

依赖关系

依赖关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。

在 UML 类图中,依赖关系使用带箭头的虚线来表示,箭头从使用类指向被依赖的类。下图所示是司机和汽车的关系图,司机驾驶汽车:

image.png

继承关系

继承关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系,是一种继承关系。

在 UML 类图中,继承关系(泛化关系)用带空心三角箭头的实线来表示,箭头从子类指向父类。在代码实现时,使用面向对象的继承机制来实现泛化关系。例如,Student 类和 Teacher 类都是 Person 类的子类,其类图如下图所示:

image.png

实现关系

实现关系是接口与实现类之间的关系。在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作,default 修饰的默认方法可以不用实现。

在 UML 类图中,实现关系使用带空心三角箭头的虚线来表示,箭头从实现类指向接口。例如,汽车和船实现了交通工具,其类图如下图所示:

image.png

对象图

对象图是一种特殊的类图,它显示出的不是类而是类的实例。对象图在显示一小部分系统的结构关系时,特别是有递归关系的结构时非常有用。

表示法

在对象图中,每一个长方形都代表一个实例。实例的名字是有下划线的,这样可以区分一个长方形所代表的是类还是对象。只要图的含义是清楚的,那么对象的名字或者类的名字可以从图中省略。

image.png

时序图

作为交互图的一种,序列交互图按照时间顺序从上往下显示每个使用案例。

表示法

在一个时序图中,垂直的虚线叫做生命线,它代表一个对象存在的时间。每一个箭头都是一个调用,这个箭头从调用者对象连接到接收者对象的生命线上的激活条上。每一个激活条代表调用所持续的时间。

image.png

状态图

定义一个具有有限个内部状态的机器,因此状态图又称为有限状态机,对象被外界的事件激发,从而从一个状态转换到另一个状态。

表示法

黑点表示起始状态,方框表示具体状态。从起始状态到具体状态的、有箭头的连线表示状态的过渡。过渡连线的标签通常分为两部分,由一个斜线分开,斜线的第一部分是引起状态过渡的事件,第二部分是事件发生所引起的操作,本例中,只有第一部分,没有第二部分,因为瓶子没有动作。

反身过渡连线,表示事件发生时,对象会过渡回当前状态。本例中,“未满”状态有反身过渡连线,表示瓶子在被加灌汽水是一个持续不断的过程。

方括号中的事件是发生的保护条件,本例中,“已加灌量 < 容量”,它是保证过渡关系发生的条件。

状态可以嵌套,一个状态中可以有别的状态。大的状态叫做父状态或者超状态,小的状态叫做子状态。

image.png