软件架构通常用组件及其交互来描述。虽然标准类图展示了静态关系,但它们往往无法揭示复杂分类器的内部组成。这正是“UML复合结构图变得至关重要。它提供了分类器内部结构的详细视图,展示了其各个部分如何相互作用以满足系统需求。
本指南探讨了创建这些图表的机制。我们将研究核心元素、符号表示和实际应用。到最后,您将掌握如何清晰无误地建模复杂的嵌套结构。

🧩 什么是复合结构图?
复合结构图(CSD)是一种UML图,用于描述分类器的内部结构。它关注构成整体的各个部分以及这些部分用于通信的接口。与关注属性和操作的类图不同,CSD关注的是组合关系和交互。
可以将复合结构图视为软件组件的X光片。它揭示了引擎盖下的内部机理。这在处理以下情况时尤其有用:
- 复杂的嵌套结构
- 具有多个接口的组件
- 需要严格边界定义的系统
- 高度依赖委托和端口的架构
该图使架构师能够可视化系统是如何由更小、可重用的组件构建而成的。它明确了内部组件与外部环境之间的契约关系。
🛠 核心元素与符号表示
要绘制有效的UML复合结构图,您必须理解其构成要素。每个元素都有特定用途和视觉表现形式。
1. 部分
部分表示分类器内部结构的一个组成部分。它是存在于复合体内的分类器实例。部分具有名称和类型。
- 视觉表现: 一个带有 <<part>> 构造型的矩形,或仅显示部分名称和类型。
- 角色: 部分可能在交互中扮演特定角色。
- 可见性: 部分可以是公共的、私有的或受保护的。
2. 端口
端口是部分或分类器的交互点。它们定义了部分如何与外部世界或其他部分连接。端口封装了部分提供的或需要的接口。
- 提供的接口: 用棒棒糖符号表示,表示向外部提供的功能。
- 需要的接口: 用插座符号表示,表示需要从外部获取的功能。
- 方向性: 端口可以是输入、输出或两者兼具。
3. 角色
当一个部件连接到连接器时,它会以特定角色进行连接。角色定义了该部件在协作中的参与方式。例如,数据库部件可能扮演“存储”的角色,而控制器部件则扮演“管理”的角色。
4. 连接器
连接器表示部件之间或部件与端口之间的连接。它们定义了数据或控制流的路径。
- 绑定连接器: 将提供的接口连接到所需的接口。
- 委托连接器: 将复合体的端口连接到内部部件的端口。
📊 对比:类图 vs. 组合结构图
理解何时应使用组合结构图而非类图,对于有效建模至关重要。以下是两者的区别分析。
| 特性 | 类图 | 组合结构图 |
|---|---|---|
| 关注点 | 属性和操作 | 内部组成与交互 |
| 粒度 | 逻辑结构 | 物理或逻辑组成 |
| 关系 | 关联、聚合、继承 | 部件、端口、连接器、角色 |
| 复杂性 | 扁平结构 | 支持嵌套结构 |
| 用途 | 通用数据建模 | 组件架构设计 |
对于一般的数据关系,使用类图。当组件的内部连接对系统行为有显著影响时,使用组合结构图。
🛤 逐步指南:创建组合结构图
遵循此逻辑流程,从零开始构建图表。此工作流程确保了一致性和清晰性。
步骤 1:定义分类器
首先确定您想要分析的分类器。这通常是一个需要内部分解的复杂类或组件。绘制代表该分类器的主要矩形。
步骤 2:识别内部部件
将分类器分解为其组成部分。问自己:构成该系统的较小组件有哪些?将它们列在主矩形内的部件中,并为每个部件分配类型。
步骤 3:定义接口
确定每个部件所暴露的功能以及它所需的功能。在相关部件上绘制棒棒糖符号表示提供的接口,绘制插座符号表示所需的接口。
步骤 4:连接部件
在部件之间绘制连接器。确保每个所需接口都连接到相应的提供接口。如果需要通过主分类器的端口暴露内部功能,请使用委托连接器。
步骤 5:添加角色和多重性
用角色标记连接器的两端。如果一个部件可以有多个实例或关系,请指定多重性。这能提高模型的精确度。
💡 实际示例:汽车控制系统
让我们将这些概念应用于一个实际场景。想象一下,建模一辆自动驾驶汽车的控制系统。
- 分类器:VehicleControlSystem
- 部件:
- SensorModule(类型:SensorArray)
- ProcessingUnit(类型:CPU)
- ActuatorModule(类型:MotorController)
- 端口:
- SensorPort(所需:RawData)
- CommandPort(提供:ControlSignal)
在此模型中:
- 而SensorModule提供原始数据。它通过绑定连接器与ProcessingUnit连接。
- 而处理单元 分析数据并需要一个控制信号接口。
- 该执行器模块 提供控制信号。它连接到处理单元。
- 该车辆控制系统 暴露一个 命令端口 该端口将请求委托给执行器模块。
此结构展示了外部命令如何通过内部处理流向物理执行器。它清晰地说明了数据路径,而不会使高层设计变得杂乱。
🎯 建模的最佳实践
为保持清晰性和实用性,请在绘制图表时遵循以下指南。
- 限制嵌套深度:过于深层的嵌套结构会变得难以阅读。如果某个部分需要自己的内部图表,应考虑为其创建单独的图表。
- 使用清晰的命名:避免使用如“Part1”之类的通用名称。应使用如“数据库连接器”或“用户界面”等描述性名称。
- 尽量减少交叉连接:尽量将连接器保持在分类器内部。如果某个部分连接到外部系统,应使用委托连接器指向主分类器的端口。
- 保持符号一致:使用标准的UML符号。不要自行发明自定义图标。
- 聚焦于交互:不要建模每一个属性。应聚焦于定义行为的接口和连接。
🔍 应避免的常见陷阱
即使是经验丰富的建模者也会犯错。以下是一些需要警惕的常见问题。
- 混淆端口与接口:端口是交互点;接口是一种契约。端口实现接口。
- 图表过于复杂:如果图表跨越多页,很可能包含的组件过多。应分解该分类器。
- 缺失委托 如果内部部件向外部提供所需服务,则必须使用委托连接器连接到主端口。
- 忽略多重性: 未指定部件实例的数量可能导致实现错误。
📈 何时使用此图
并非每个组件都需要复合结构图。当满足以下条件时使用:
- 内部连接复杂且影响外部行为。
- 您需要指定内部部件的重用。
- 您正在为组件部署定义严格的边界。
- 您需要记录接口的委托。
对于具有简单属性的简单类,类图已足够。将复合结构图保留用于高价值的架构决策。
🧠 高级概念
随着您技能的提升,可以探索该符号的高级功能。
代理端口
代理端口充当尚未实现的部件的占位符。它允许您在组件构建之前设计系统流程。
值规范
您可以在部件定义中指定某些属性的固定值。这对于配置参数非常有用。
行为协议
端口可以与状态机关联。这定义了该端口上允许的交互顺序。
📝 关键要点总结
总结设计工作的核心要点:
- 复合结构图揭示了内部组成。
- 部件、端口、角色和连接器是核心元素。
- 明确区分提供的接口和所需的接口。
- 使用委托连接器来暴露内部功能。
- 通过避免过度嵌套来保持图表的可读性。
- 根据系统的运行时行为验证您的模型。
掌握这种图示类型可以增强您的架构文档深度。它弥合了高层设计与底层实现细节之间的差距。遵循这些指南,您可以创建清晰、可维护的模型,有效服务于您的团队。
❓ 常见问题
我可以将类图和复合结构图结合使用吗?
可以。使用类图表示整体数据模型,使用复合结构图表示特定的复杂组件。它们相辅相成。
我需要在组合结构图中展示每一个方法吗?
不需要。关注交互即可。方法属于部件的操作,而不是结构本身。
如果我有一个部件的多个实例呢?
在连接器的一端指定多重性。这表示所需的或允许的实例数量。
这个图是否被所有建模工具支持?
大多数现代建模工具都支持标准UML符号,但一些工具在高级功能(如嵌套的组合结构)上可能存在特定限制。
🏁 最后思考
建模软件架构是一种追求清晰性的练习。这个UML组合结构图提供了一个强大的视角,用于分析系统是如何构建的。通过理解部件、端口和连接,你可以掌控设计的复杂性。使用这个工具来记录、沟通和验证你的架构决策。经过练习,这些图表将成为你设计工作流程中不可或缺的一部分。












