Unified Modeling Language UML 类图
什么是UML类图?
统一建模语言(UML)是一种用于软件系统可视化、构造和文档化的标准建模语言。UML定义了多种图,其中类图是最核心的静态结构图。它展示了系统中的类、接口、它们之间的协作关系以及内部结构,是面向对象分析与设计的基础工具。
类图能帮你回答这些问题:
- 系统中有哪些核心概念?(类)
- 每个类负责哪些数据和行为?(属性和方法)
- 类与类之间如何依赖、继承或协作?(关系)
对于初学者,掌握类图是理解设计模式、阅读框架源码以及进行系统设计的第一步。
类的基本表示
在UML类图中,一个类通常用一个分为三层的矩形表示:
+-------------------+
| ClassName | ← 类名(首字母大写,正体)
+-------------------+
| - attribute: Type | ← 属性层
| + operation():void| ← 操作层
+-------------------+
1. 类名
- 如果是具体类,类名使用普通字体。
- 如果是抽象类,类名使用斜体。
- 如果是接口,类名上方会加上
<<interface>>构造型。
2. 属性(Attributes)
属性定义了类的数据成员,格式为:
可见性 名称: 类型 [多重性] = 默认值
例如:- name: String [1] = "未命名"
3. 操作(Operations)
操作即方法,格式为:
可见性 名称(参数列表): 返回类型
例如:+ setName(newName: String): void
4. 可见性(Visibility)
UML使用符号表示访问级别:
+public-private#protected~package(默认包内可见)
关系类型与画法
类与类之间的关系是类图的灵魂。正确表达关系能让模型一目了然。
关联(Association)
表示一个类“知道”另一个类,是一种静态的、语义上的连接。通常用一条实线连接两个类,并可在两端标注角色名和多重性。
Student Course
+-----------+ +-----------+
| |--------| |
+-----------+ +-----------+
enrolledIn hasStudent
在实线上可添加箭头表示导航方向。没有箭头通常表示双向关联(或未指定)。
聚合(Aggregation)
表示“整体-部分”的弱拥有关系,部分可以脱离整体独立存在。用空心菱形指向整体。
Team ◇--------- Player
(整体) (部分)
例如:一个球队由多名球员组成,球员离开球队后依然可以存在。
组合(Composition)
强拥有关系,部分的生命周期由整体管理,整体销毁时部分也会一同销毁。用实心菱形指向整体。
House ◆--------- Room
(整体) (部分)
例如:房子由房间组成,拆掉房子房间就不复存在。
泛化(Generalization)
表示继承关系,子类继承父类的特征。用带空心三角箭头的实线,箭头指向父类。
Animal
/|\
|
---------------
| |
Dog Cat
抽象类或方法用 斜体 表示。
实现(Realization)
类实现接口的关系。用带空心三角箭头的虚线,箭头指向接口。
<<interface>> ImplementingClass
Flyable ◁ - - - - - - Bird
依赖(Dependency)
一个类使用另一个类作为局部变量、参数或返回值,是一种临时的、较弱的关系。用带箭头的虚线表示,箭头指向被依赖的类。
Order - - - - > Payment
(使用)
多重性(Multiplicity)
多重性表示一个类的实例可以与对方多少个实例发生关联。标注在关联线的一端。
常用表示法:
1严格1个0..10或1个*或0..*任意数量(包括0)1..*至少1个n..m指定范围,如2..4
示例:
Customer 1 ----------- * Order
一个客户可以有0或多个订单,一个订单恰好属于一个客户。
抽象类与接口的明确表示
- 抽象类:类名和抽象操作用斜体书写,也可在类名下添加
{abstract}属性。 - 接口:有两种画法
- 与类相似的矩形,顶部标注
<<interface>>。 - 棒棒糖表示法(lollipop notation),一个圆圈连接实现类,节省空间。
- 与类相似的矩形,顶部标注
注释(Note)
注释用于添加说明、约束或限制,可以用虚线连接到目标元素。
┌──────────────────────────┐
│ 需要持久化到数据库 │
└──────────────────────────┘
\
\
+--------------+
| User |
+--------------+
一个完整的类图示例
下面是对一个简单电商系统中部分类的建模:
<<interface>>
Payable
+------------------+
| + process(): void |
+------------------+
△
| (实现)
+-----+-----+
| Payment |
+-----------+
| - amount |
+-----------+
Customer 1 ----------------- * Order
+--------------+ +-----------------+
| - name | | - orderId |
| - email | | - date |
+--------------+ +-----------------+
|1
| (组合)
◇
* |
+-----------------+
| OrderLine |
+-----------------+
| - quantity |
+-----------------+
| + calcSubtotal()|
+-----------------+
*
| 关联
1
+-----------------+
| Product |
+-----------------+
| - name: String |
| - price: double |
+-----------------+
解读:
Customer和Order是1对多的关联。Order和OrderLine是组合关系,订单被删除时订单行也删除。OrderLine关联一个Product,多重性为1。Payment实现了Payable接口。
绘制工具推荐
- 在线工具:draw.io, Lucidchart, PlantUML (文本驱动), Visual Paradigm Online
- IDE插件:Visual Studio Class Designer, IntelliJ IDEA内置UML, Eclipse Papyrus
- 专业建模:Enterprise Architect, StarUML
初学者常见误区
- 混淆聚合与组合:关键看部分能否独立存在。能独立存在用聚合,不能则用组合。
- 滥用双向关联:尽量使用单向关联,更清晰,也避免循环引用。
- 忽略多重性:不标多重性意味着“未指定”,容易产生歧义。
- 把依赖当成关联:如果一个类只在方法内部临时使用另一个类,不要画成关联。关联表示持久的引用(通常作为成员变量)。
- 属性与方法过度细化:类图只展示关键特征,getter/setter等简单方法通常不必全部列出。
总结
UML类图是面向对象世界的通用语言。通过掌握类、关系、多重性和可见性的表示法,你可以清晰地表达软件设计,与团队高效沟通。从今天起,尝试用类图来绘制你手上的项目结构,你会发现代码架构变得更加直观。