许多大型软件系统都是模块化的,一个模块可能就表示一个子系统或者功能,等等。因此,在开发整个软件系统之前,明确软件模块组成是很重要的。我们就可以使用UML组件图对软件系统结构进行建模。
组件图是表示一个软件系统的组件构成及其组件的依赖关系的一种图,主要是描述软件的构成,但通常不包含关于系统中硬件的构成情况。
1,组件图基本要素
首先,我们来看一下组件图中的基本要素的表示方法。
(1) 组件
组件(Component)是组件图最基本的要素,表示软件系统中一个组件/模块等,组件可以是:
- 某个源代码文件或者相近的源代码文件集合(例如
java
文件,jar
文件) - 子系统模块(比如一个电商后台系统,用户模块和订单模块都可以视作一个组件)
- 动态链接库(例如
dll
、so
文件)
总的来说,组件就是软件系统中遵从一组接口且提供实现的一个部件,它的表示方式如图:
可见组件有两种表示方法,可以是:
- 一个矩形框左侧附带两个小矩形框
- 一个矩形框,在右上角带上组件图标
这两种表示方法都是一样的,没有区别,不过在UML 2.x规范中,更偏向于使用后者(上图组件2)。
在组件矩形框中,通常会标明组件类型和组件名称,组件类型使用«»
包围,常见的类型:
library/dll
动态链接库类型组件file/cpp/java
源代码文件类型组件artifact
可表示一个Java中的jar
文件- ...
类型没有统一的规范,只要能清晰表达意思即可。
此外,对于更复杂的组件,也就是一个组件里面还有子组件,可以表达如下:
在父组件的大矩形框里面,放子组件即可。
(2) 组件关系
组件最重要的关系就是提供接口和使用接口,此外组件之间还有依赖等关系,如下图表示:
上述:
- 圆球(Lollipop):表示一个组件提供一个接口
- 半圆(Socket):表示一个组件需要或者接入一个接口
- 虚线箭头:表示一个组件直接依赖另一个组件
- 虚线三角箭头:表示一个组件实现了另一个组件的功能
(3) 端口
端口(Port)是UML 2.x规范新增要素,表示组件的一个交互点,使用一个附着在组件边上的小方框表示:
看起来端口好像和提供接口符号作用很像,但事实上端口提供了更加丰富的功能,它不仅表示“提供了哪些功能”,更强调“通过哪个途径”、“在什么条件下”、“以什么方式”进行交互。
2,组件图绘制示例
下面,我们通过几个简单示例来学习如何绘制组件图。
(1) 接口的提供和接入
假设现在有用户服务组件和订单服务组件,其中用户服务:
- 提供用户登录接口
- 提供用户信息查询接口
对于订单服务:
- 提供查询订单接口
此外,订单服务需要接入用户服务的用户信息查询接口。
上述系统组件我们可以表示如下图:
可见,使用连接在组件的小圆球可以表示一个组件所提供的接口,而连接在组件的半圆表示这个组件所需要的接口,而半圆和圆球相对接则表示一个组件接入了另一个组件的对应功能。
(2) 组件依赖
基于上述场景,假设两者都依赖于一个日志模块,需要调用其中的代码或者内部接口实现日志记录,那么可以表示如下图所示:
看起来依赖关系和提供/接入接口关系(球形与半圆)很类似,但事实上还是有区别的:接口提供和接入关系更加凸显出组件对外暴露的功能性接口,而组件依赖通常表示的是组件之间直接的代码调用,或者内部接口调用。
(3) 抽象接口与实现
在很多场景下,我们可能需要遵循依赖倒置原则以及里氏替换原则来设计软件,也就是说提供一个接口门面,并由多个模块实现。例如Java中的SPI机制就是这样。
例如Slf4J就是一个日志门面,它只提供抽象接口表示所需功能和调用入口,并不提供实际实现,而Log4J和Logback则是实现了Slf4J。类似地,我们可以使用组件图表达它们的关系如下:
在抽象接口上,我们仍然是使用连接在组件的圆球表示其声明的功能性接口,然后使用虚线和三角箭头连接实现者和门面。
(4) 端口的使用
对于更加复杂的情况,我们可以使用端口。端口直接附在组件边上就行:
对于这样简单的场景,使用端口看起来不就是多此一举吗?但事实上,端口除了向上图一样,和接口相关联之外,还有更多的作用,我们这里列举几个常见的使用场景。
① 表示输入/输出途径
接口可能更加偏向于组件的功能,而端口事实上更偏向于表达操作途径。什么是操作途径呢?比如:
- 访问该组件的网络协议
- 传入该组件的数据格式
- 访问该组件的相关约束
- ...
上述都可以视为操作途径。
比如说某个注册中心组件,支持使用HTTP协议和gRPC协议注册应用程序,也就是说虽然是同一个功能,都是注册应用程序,但是它支持两种不同的协议,也就是说这个接口有两种操作途径来调用。可以表示为如下图:
可见一个端口就是一个协议,即一个途径,它们关联到同一个接口。
② 接口分组
端口事实上还有接口分组的作用,假设一个组件有多组接口,那么可以将功能相近的接口关联到一个端口上面:
3,使用Draw.io绘制组件图
Draw.io是一个开源的绘图软件,它包括了非常多的图案模板,我们可以使用它绘制各种各样的图。
该软件可以直接在线使用,也可以下载客户端:
在之前的UML类图绘制教程中,已经讲解了如何使用Draw.io软件,这里就不再详细讲解了,在左侧栏UML和UML 2.5分类中,可以找到相关的组件图要素。
示例组件图矢量文件:传送门