进阶 #software-eng#uml
UML 建模
UML(统一建模语言)是用图形表达软件设计的标准语言——类图描述结构,时序图描述交互,用例图描述需求
🗺️ “画出来”比”说出来”更容易理解
你和同学讨论一个系统的设计——“这里应该有一个 User 类,它和 Order 类是一对多关系……”你描述了半天,同学一脸茫然。
但如果你拿出一张图:
User ──── 1:N ──── Order
同学瞬间就懂了。
UML(Unified Modeling Language,统一建模语言) 就是软件设计的”共同语言”——用标准化的图形符号表达软件的结构和行为。不管你是用 Java、Python 还是 C++,UML 符号都是一样的。
📐 **类比:建筑施工图”
建筑师画了一张施工图——用标准符号(墙是双线、窗户是缺口、门是弧线)。不管在北京还是纽约,施工队都看得懂。
UML 就是软件的”施工图符号”——不管你是 Java 程序员还是 Python 程序员,类图、时序图的符号都是一样的。
📊 三种最常用的 UML 图
① 用例图(Use Case Diagram)——系统有啥功能?
从用户视角描述系统提供的功能:
┌────────────────────────┐
│ 学生选课系统 │
│ │
┌──────┐ │ ┌───────────┐ │
│ 学生 │─────→│ 登录 │ │
└──────┘ │ └───────────┘ │
│ ┌───────────┐ │
┌──────┐ │ │ 浏览课程 │ │
│ 教师 │─────→│ │ │
└──────┘ │ └───────────┘ │
│ ┌───────────┐ │
┌──────┐ │ │ 选课 │ │
│ 管理员 │─────→│ │ │
└──────┘ │ └───────────┘ │
└────────────────────────┘
| 元素 | 形状 | 含义 |
|---|---|---|
| 角色(Actor) | 火柴人 | 使用系统的人或外部系统 |
| 用例(Use Case) | 椭圆 | 系统提供的一个功能 |
| 系统边界 | 矩形框 | 系统的范围 |
用例图适合和客户沟通——不需要懂技术就能理解。
② 类图(Class Diagram)——系统的数据结构长啥样?
描述系统中类的定义以及类之间的关系:
┌─────────────────┐
│ User │
├─────────────────┤
│ - id: int │ ← 属性
│ - name: string │
│ - email: string │
├─────────────────┤
│ + login() │ ← 方法
│ + getOrders() │
└────────┬────────┘
│ 1
│
│ (一对多关联)
│ *
┌────────┴────────┐
│ Order │
├─────────────────┤
│ - id: int │
│ - total: float │
│ - status: string │
├─────────────────┤
│ + pay() │
│ + cancel() │
└─────────────────┘
类之间的关系:
继承: 子类 ──▷ 父类 (实线三角箭头)
实现: 类 - -▷ 接口 (虚线三角箭头)
关联: 类A ───→ 类B (一个类知道另一个类)
聚合: 类A ──◇ 类B (整体-部分,部分可独立存在——班级和学生)
组合: 类A ──◆ 类B (整体-部分,部分不可独立——订单和订单项)
依赖: 类A - -→ 类B (临时使用——方法参数中用到)
# 对应上面的类图
class User:
def __init__(self, id: int, name: str, email: str):
self.id = id
self.name = name
self.email = email
self.orders = [] # 1:N 关联
def login(self):
pass
def get_orders(self):
return self.orders
class Order:
def __init__(self, id: int, total: float):
self.id = id
self.total = total
self.status = "pending"
def pay(self):
pass
def cancel(self):
pass
③ 时序图(Sequence Diagram)——多个对象怎么协作?
描述多个对象之间按时间顺序的交互过程:
学生 选课控制器 课程
│ │ │
│── 选课(courseId) ─────→│ │
│ │── checkCapacity() ──────→│
│ │←──── capacity_ok ────────│
│ │── enroll(studentId) ────→│
│ │←──── success ───────────│
│←── "选课成功" ────────│ │
| 元素 | 含义 |
|---|---|
| 生命线(Lifeline) | 竖虚线——代表一个对象随时间存在 |
| 激活条(Activation) | 竖条——对象执行操作的时间段 |
| 消息(Message) | 箭头——一个对象向另一个对象发消息 |
时序图适合设计阶段讨论交互流程——“先调这个方法还是先调那个?”
🧩 其他 UML 图(简要了解)
| 图类型 | 用途 | 什么时候用 |
|---|---|---|
| 活动图 | 描述业务流程、并行分支 | 工作流分析 |
| 状态图 | 描述对象的状态变化(如订单:待支付→已支付→已发货) | 有复杂状态的对象 |
| 部署图 | 描述物理部署(服务器、数据库在哪) | 运维架构设计 |
| 组件图 | 高级别的模块依赖 | 系统架构概览 |
💡 UML 的使用建议
# 实际项目中,不需要"画所有 UML 图"
# 关键是:选合适的图解决特定的沟通问题
rules_of_thumb = {
"和客户沟通需求": "用例图",
"讨论数据结构": "类图",
"讨论交互流程": "时序图",
"讨论复杂业务": "活动图",
"讨论对象状态": "状态图",
}
⚠️ 不要过度建模:UML 的目的是沟通,不是”交作业”。画到”刚好能让别人理解”的程度就够了,不需要追求”完美的 UML 标准”。
现代软件开发中,代码本身就是设计文档——UML 图是”帮助理解”的工具,不是”替代代码”的东西。
📝 小结
| 概念 | 一句话 |
|---|---|
| UML(统一建模语言) | 软件设计的标准图形语言 |
| 用例图 | 系统功能和用户——和客户沟通 |
| 类图 | 类及其关系——数据结构设计 |
| 时序图 | 对象间交互顺序——流程设计 |
| 活动图 | 业务流程和并行——复杂业务分析 |
| UML 的使用原则 | 够用就行——目的是沟通,不是交作业 |
🎯 小练习:为”图书馆借书系统”画一个简单的类图(包括:User、Book、BorrowRecord 三个类,标注它们之间的关系)和一个时序图(描述”用户借书”的完整交互流程)。
为什么先学这个? UML 是设计的”语言”,而设计的好与坏需要用原则来衡量——SOLID 原则。