组件图(Component Diagram)又称构件图,是UML中描述一个系统中的物理方面的图形,它是用来描述构成系统的各个组件、组件提供的接口与需求的接口、端口以及它们之间关系的图。这种图在基于组件开发的系统建模中很重要。组件图可以帮助用户理解系统的结构。
组件图中主要包括组件、接口及其它们之间的关系三种元素。
1. 组件
组件(Component)是定义了良好接口的、可重用的、可替代的物理实现单元,它一般表示实际存在的、物理的物件。程序源代码、可执行文件、子系统、一个脚本、动态链接库(DLL)、ActiveX控件都可以成为系统中的组件。组件隐藏了内部实现的细节,仅通过接口提供服务。
我们可以把组件理解为一个黑盒子,这个黑盒子使用接口来公开其公共可见的属性及操作,这一点与类非常相似。在UML1.x版本中,一个标准的组件使用如下的图形来表示。
UML 1.x:标准的组件
而在UML2.x中一般使用如下的图形来表示一个组件:
UML 2.x:标准的组件
也可以使用类似类的矩形框加上构造型<<component>>来表示组件,如下图所示:
2. 接口
组件中的接口主要分为两类:提供接口(Provided Interface)和需求接口(Required Interface)。
(1)提供接口又称导出接口,是组件提供的服务的集合。
提供接口是由组件本身直接实现的接口、或者是由实现组件的类之一实现的接口,或者是由组件的公共端口提供的接口。提供接口可以使用接口与组件之间的实现关系来表示,可以在组件图标的边框上使用类似棒棒糖式(lollipop)的图标来表示。如下图所示:
提供接口简化表示
这个图表示WeatherServices组件提供或实现了WeatherForecast接口。它可以认为是下图的简化表示方法:
提供接口
(2)需求接口又称导入接口,是组件请求其它组件相应服务时遵循的接口。
需求接口通过依赖关系来表示,需求接口可以使用插座(Socket)的图标连接到组件边框上来表示,如下图所示:
需求接口简化表示
上面这个图表示UserServices组件需要(依赖)IOrderServices接口。它可以认为是下图的简化表示方法:
需求接口
作为一种可选方式,可以把组件的接口或组件的操作和属性列在组件图标下边的隔室里。
上图表示,UserServices接口提供的接口有IUserServices,需求的接口有IOrderServices。
端口
端口用于描述组件或类与它的环境、与其它类、与其它组件或内部部件的交互点。这个交互点一般是组件或类的一个属性,默认情况下,端口具有公共可见性。端口使用类或组件边框上的一个小矩形来表示,如下图所示:
端口
上图表示BorrowServices组件有一个borrowPort端口。接口通过端口来提供服务或获得服务,下图表示了这种情况:
3. 组件图中的关系
组件图中的关系主要包括两种:依赖关系和实现关系。
(1)依赖关系
组件图中的依赖关系与类图中相同,都是“供应者-客户”关系(supplier-client),使用虚线箭头由客户(client)组件指向供应者(supplier)组件。下图表示组件“borrowBook”依赖于组件“Book”,其中,“borrowBook”是客户组件,Book是供应者组件:
“borrowBook”依赖于组件“Book”
下图也表示了两个组件之间的依赖关系,它表示了borrowBook组件的一个需求接口依赖于Book组件的一个提供接口,一般这种依赖关系都是从插座接口引出指向棒棒糖接口:
依赖关系
上图也可以简化成下面的形式,表示了borrowBook使用某个需求接口与Book组件的提供接口产生依赖关系。这种图在UML2.x中被定义为连接:
依赖关系简化
(2)实现关系
组件之间的实现关系表示一个组件实现了另外一个组件。这与类和接口之间的实现关系相同。下面第一个图表示组件borrowBook实现了组件IBorrowBook。如果IBorrowBook组件仅包含一个接口的话,也可以使用第二个图来表示(见上面关于组件提供接口的说明)。备注:组件实现了一个接口意味着组件支持接口中的所有操作。
实现关系
Scott W.Ambler在其著作《The Object Primer:Agile Model-Driven Development with UML 2.0》第三版中,给出了关于组件建模技术的一些方法和技巧:
《The Object Primer:Agile Model-Driven Development with UML 2.0》
在实际组件建模中可以采用自顶向下的方法,也可以使用自底向上的方法。使用自顶向下的建模方法可以使设计人员能够更清晰的了解软件的未来架构,但这种方法容易导致系统的过度架构化,从而导致系统的过度建模,易使设计人员过度关注细节,而忽略了客户的真正需求。
使用自底而上的方法可以在类建模的基础上把已设计的类进行组件化,把系统中可重用的部分分离出来,或者将应用程序进行拆分,以便把任务轻松地分配给相应的团队。
在组件建模中可以使用如下步骤或原则进行建模:
(1)保持组件的内聚性
一个组件应保持其功能单一性或功能相关性。如,一个组件仅包含某类用户的用户界面、或者仅包含大规模领域概念的业务类,或者仅包含公共基础概念的技术类。
(2)将用户界面类分配给应用程序组件
用户界面类,如页面、报告以及实现相关逻辑的类,应该放在带有“application”构造型的组件中。如Java中JSP页面、servlet和Swing类等。
(3)把技术类分配到基础架构组件中
实现系统级服务的类,如安全、持久性或中间件,应该分配到带有“infrastructure”构造型的组件中。
(4)定义类的契约
类契约是指能够直接响应其它对象发送的消息的方法(操作)。如在Books类中很可能包括getBookInfo()这样的方法,这样的方法能够响应来自其它组件中对象发送的消息。为了很好的识别组件,你可以忽略所有非类契约的操作,原因是这些操作对促进分布在不同组件中的对象之间进行通信不会提供太大帮助。
(5)把一个具有层次结构的所有类(如类的继承或聚合层次结构)分配到相同组件中。
(6)识别领域组件
若干类相互协作以完成特定的任务,这些类满足内聚要求,从而成为一个领域组件。其它类或组件能够通过向该领域组件发送消息以请求获得信息或执行操作。领域组件对外显示出其简单性,但其内部通常很复杂。领域组件设计的目标是减少网络通信,而使大多数信息流发生在其内部。
(7)确定业务类的协作类型
服务器类是接收消息但不发送消息的类;客户类是发送消息但不接收消息的类;客户/服务类是兼有发送消息和接收消息的类;在确定好每个类的分布类型后,就可以开始确定潜在的领域组件了。
(8)把服务器类归为一个组件中
纯服务器类属于领域组件,他们是应用程序中消息流的“最后一站”。
(9)将仅为某客户端类服务的组件合并到其客户组件中
如果一个领域组件仅为某一个组件提供服务,那么可以把这两个组件合并为一个组件。
(10)单纯的客户端类不应归到领域组件中
客户端类只生成消息而不接收消息,不应属于领域组件。领域组件的目的是响应消息,客户端类很可能属于应用程序组件。
(11)高度耦合的类应归为一个组件中
两个频繁协作的类应位于相同的领域组件,以减少两个类之间的网络流。即,高度耦合的类应放在一起。
(12)遵循最小化组件间的消息流原则
在确定一个客户类/服务类属于哪个组件时,要充分考虑流入和流出类的信息流。组件内的通信通常是在内存中对象之间简单的消息发送。组件间的通信往往需要消息的转换、传输等额外的支出。
(13)定义组件的契约
每个组件应向客户提供服务,这样的服务即为组件的契约。
1,新建组件图文件
注册/登录ProcessOn后,进入个人文件页,点击【新建】按钮创建一个空白UML文件,如下图所示的操作:
创建空白UML文件
2,往编辑区添加组件
在编辑器左侧UML组件图中,选择“组件”,然后把它拖曳到右侧编辑区中来。
添加UML组件图元素
3,文件重命名
双击组件符号,输入或修改组件的名称。
4,调整组件显示大小
如果需要调整组件的大小,可以选中组件,在其周围会出现若干个白色的小方块,如下图所示:
鼠标到上面会变成双向箭头的形状,然后按住鼠标左键,通过拖拽来改变图形的显示大小。
5,设置样式
修改字体选中组件后,在编辑器顶部工具栏内可以修改字体、颜色以及字体的大小、是否加粗、是否有下划线等设置,如下图所示:
6,删除一个组件
在ProcessOn中,要彻底删除一个组件,可以选中组件之后,按下“Delete”或“Backspace”键,或者右击组件,然后选择“删除”,则可以彻底删除该组件。
7,添加和分配组件的接口
添加完组件后,从左侧UML组件图形中拖拽“接口”图形到右侧编辑器区,并拖拽文本到接口下方,直接输入接口的名称。
接着,点击组件的一端后按住鼠标左键到对应的接口上,松开鼠标即可以为组件指定其要实现的接口。分配完接口后的组件及操作对话框后的情形如下图所示:
为组件指定实现的接口后的样子如下图所示:
它表示IBook和IReader接口在组件BorrowBooks中实现的,也表示BorrowBooks提供了IBook和IReader两个接口(提供接口)。用户也可以使用同样的方法,把组件中包含的类分配到某个组件中。
8,添加依赖关系
使用步骤(7)的方法也可以在组件图中添加依赖联系。备注:可以在编辑器顶部工具栏对表示依赖关系的线条形状、粗细、箭头类型等进行修改。
如下图显示了组件“Fine”和接口“IFineRecords”之间的依赖关系。它相当于组件的需求接口(Required Interface)。
下面是图书馆借阅系统中的组件图:
UML往期内容推荐