vault backup: 2026-06-13 20:13:56

This commit is contained in:
2026-06-13 20:13:56 +08:00
parent 4ad09b8153
commit 9a3d58dd3b
16 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,271 @@
# 第1章 需求工程
> **考试重要度**:★★★★
> **核心内容**:需求的定义与层次、需求获取与分析技术、需求文档编写、需求管理
---
## 📢 开篇故事:一个失败的工资系统
A公司从300人发展到5000人原来的手工工资管理方式完全跟不上了。总经理李云找到技术主管王奇说
> "我们急需一个新工资系统!员工自己登记时间卡,系统自动算工资,五个月搞定,明白吗?"
王奇说:"能不能再详细说说?比如有哪些角色用这个系统?每类人需要什么功能?数据怎么流转?"
李云不耐烦:"我不就是用户吗?你们自己看着办不就行了?"
💬 **这个故事告诉我们什么?**
1. **老板 ≠ 用户**。老板说的是"业务需求"(高层次目标),但不是具体"用户需求"。
2. **需求不是想当然的**。开发人员不能凭空猜测用户要什么。
3. **不同角色有不同需求**。出纳、会计、财务主管、普通员工——每个人要的功能都不一样。
4. **需求需要花时间获取**。反复沟通、深入调查,急不得。
---
## 💡 一、什么是软件需求?
> **一句话定义**:需求就是用户对软件系统"应该做什么"和"应该做到什么程度"的期望。
### 三个权威定义
| 来源 | 定义 |
|------|------|
| **IEEE** | 用户解决问题所需的**条件或能力**;系统必须满足的**约束**;上述内容的**文档化表达** |
| **Davis** | 从软件外部可见的、满足用户的**特点、功能及属性**的集合 |
| **Sommerville** | 问题信息与系统**行为、特性、设计和实现约束**的描述集合 |
💬 **大白话**:需求就是三件事——**做什么功能**、**做到什么标准**、**有什么限制**。
---
## 💡 二、需求的三个层次
这是考试的重点!需求像一座三层金字塔:
```
┌──────────────┐
│ 业务需求 │ ← 老板视角:"我们要什么"
│ Business │
├──────────────┤
│ 用户需求 │ ← 用户视角:"我能用它干什么"
│ User │
├──────────────┤
│ 系统需求 │ ← 开发者视角:"具体怎么实现"
│ System │
└──────────────┘
```
| 层次 | 说明 | 举例(工资系统) |
|------|------|------------------|
| **业务需求** | 组织的高层次目标,回答"为什么要做这个系统" | "用计算机替代手工工资管理,五个月上线" |
| **用户需求** | 用户使用系统完成的任务,回答"用户能干什么" | "财务人员可以录入员工时间卡信息" |
| **系统需求** | 开发人员要实现的具体功能和约束,回答"系统必须做到什么" | "系统自动根据工时和销售额计算工资单" |
### 系统需求又分三类
| 类型 | 说明 | 举例 |
|------|------|------|
| **功能需求** | 系统必须提供的功能 | 录入时间卡、计算工资、生成工资单 |
| **非功能需求** | 系统的质量属性和约束 | 工资计算5秒内完成、数据不能丢失 |
| **领域需求** | 行业特有的要求 | 遵循《中国图书馆分类法》编目图书 |
---
## ✍️ 边学边练(一)
**题目**:下面哪一个是正确的需求层次顺序(从高到低)?
A. 用户需求 → 业务需求 → 系统需求
B. 业务需求 → 用户需求 → 系统需求
C. 用户需求 → 系统需求 → 业务需求
D. 业务需求 → 系统需求 → 用户需求
**答案:**
**正确答案B**
记住口诀:**"老板定方向(业务),用户说任务(用户),开发写代码(系统)"**,从抽象到具体。
---
## 💡 三、需求为什么重要?
### 数据说话
| 成功因素 | 占比 | 失败因素 | 占比 |
|----------|------|----------|------|
| 用户参与 | **15.9%** | 需求不完善 | **13.1%** |
| 管理层支持 | 13.9% | 缺乏用户参与 | 12.4% |
| 清晰的需求 | 13.0% | 资源不足 | 10.6% |
💬 **一句话**:需求的锅是最大的锅。需求搞错了,后面全白做。
### 五个常见需求败因
1. **需求不完整** — 只问了领导,没问实际操作的人
2. **缺乏用户参与** — 用户觉得"我不懂技术,你们自己弄"
3. **不切实际的期望** — "10年内每天24小时100%可用"(技术上做不到)
4. **需求变更频繁** — 今天加一个,明天改一个,后天不要了
5. **做了没人用的功能** — 开发了很多功能,实际使用率极低
---
## 💡 四、需求工程的核心流程
> **需求工程** = 所有跟需求有关的活动,分成"开发"和"管理"两大类。
```
需求开发(做对需求): 获取 → 分析 → 定义(写文档)
需求管理(管好需求): 验证 → 跟踪 → 变更控制
```
### ① 需求获取 — 怎么收集需求?
💬 **打个比方**:需求获取就像医生问诊——你不会直接让病人给自己开药,而是通过望闻问切来了解病情。
**六大获取技术**
| 技术 | 怎么做 | 适用场景 |
|------|--------|----------|
| **联合分析小组** | 用户 + 领域专家 + 分析员坐在一起 | 大型复杂项目 |
| **用户访谈** | 一对一或小组面谈 | 深入了解具体业务 |
| **问卷调查** | 发放问卷收集大量反馈 | 用户分散、人数多 |
| **观察工作流程** | 到现场看用户怎么干活 | 发现"隐形的需求" |
| **原型法** | 做个简单的界面模型给用户试用 | 用户说不清楚自己要什么 |
| **文档分析** | 研究现有的规章制度、报表等 | 理解业务规则 |
⚠️ **关键认知**:很多需求是**隐形的**——用户觉得"这还用说吗",但实际上不说就不会被实现。所以要主动挖掘。
### ② 需求分析 — 怎么理清需求?
两种基本方法:
| 方法 | 核心思想 | 使用的图 |
|------|----------|----------|
| **结构化分析 (SA)** | 把大问题分解成小问题,逐层细化 | DFD数据流图、ER图、状态转换图 |
| **面向对象分析 (OOA)** | 基于用例,用对象来组织系统 | 用例图、类图、顺序图等UML图 |
💬 **SA像切蛋糕**:一层层切,直到每一块都能一口吃掉。
💬 **OOA像拼乐高**:先找到有哪些"积木块"(类),再定义他们怎么拼在一起(关系)。
### ③ 需求定义 — 写需求文档
**两份核心文档**
| 文档 | 谁看 | 用什么语言 | 什么程度 |
|------|------|------------|----------|
| **用户需求说明书** | 用户审核 | 自然语言+业务术语 | 比较粗略 |
| **软件需求规格说明书(SRS)** | 开发团队 | 技术语言+图形模型 | 非常详细 |
💬 **区别**:用户需求说明书像"装修意向书"我要北欧风、三室两厅SRS像"施工图"客厅长5米宽4米插座位置距地30cm
### 🔑 优秀需求的七个标准
| 标准 | 含义 |
|------|------|
| **完整性** | 所有功能都说清楚了,不缺项 |
| **正确性** | 描述的功能确实是用户要的 |
| **无歧义** | 所有人读出来是同一个意思(别用"可能""差不多" |
| **可行性** | 技术上能做、预算内能做 |
| **有优先级** | 分清楚哪些先做、哪些后做 |
| **必要性** | 每个需求都有存在的理由 |
| **可验证性** | 能通过测试来确认是否实现了 |
### ④ 需求验证 — 怎么确认需求是对的?
**验证什么**
- ✅ 有效性:写的功能是不是用户真实需要的
- ✅ 一致性:有没有前后矛盾的描述
- ✅ 完备性:有没有漏掉的需求
- ✅ 可检验性:能不能设计测试来验证
**主要方法****需求评审** — 开发方和客户方一起逐条审查,签字确认后形成"需求基线"。
### ⑤ 需求跟踪
**双向跟踪**
- **正向跟踪**:需求 → 设计 → 代码 → 测试,确保每个需求都有实现
- **逆向跟踪**:代码 → 设计 → 需求,确保每一行代码都有需求来源
### ⑥ 需求变更控制
💬 **需求变更像改装修方案**——墙都砌好了你说要拆?不是不行,但要评估影响、调整预算、重新排期。
**变更控制流程**`提出变更 → 评审影响 → 审批 → 修改 → 重新确认`
---
## ✍️ 边学边练(二)
**题目**:图书馆系统有以下描述,请区分功能需求、非功能需求和领域需求。
1. 系统要能实现图书借阅和归还的登记
2. 每次借书登记必须在1秒内完成
3. 图书编目要遵循《中国图书馆分类法》
4. 借书登记出错率不超过万分之一
5. 某些文献只能在阅览室阅读,不能外借
**答案:**
-**功能需求** — 描述系统要做什么(借阅登记、归还登记)
-**非功能需求(性能)** — 描述系统要做到什么程度1秒内
-**领域需求** — 行业特有的规则约束
-**非功能需求(可靠性)** — 错误率的量化指标
-**领域需求** — 版权法对图书馆业务的特殊约束
⚠️ **易错点**:区分功能需求和非功能需求的关键在于——**功能需求说"做什么",非功能需求说"做多好"**。
---
## 📝 章末自测
**1. 填空题**
- 需求的三个层次从高到低依次是:( ___ )、( ____ )、( ___
- 优秀需求的七个特性中,"所有人读出来是同一个意思"指的是( ___ ___ )性
- 结构化分析的三个模型是功能模型DFD ___ )、( ___
**2. 简答题**
- 简述"用户需求说明书"和"软件需求规格说明书(SRS)"的区别。
- 结构化分析(SA)和面向对象分析(OOA)的核心区别是什么?
**3. 应用题**
- 某在线购物系统,请分别写出一条:业务需求、用户需求、功能需求、非功能需求。
**答案:**
**填空题答案**
- 业务需求、用户需求、系统需求
- 无歧义性
- 数据模型ER图、行为模型状态转换图
**简答题答案**
- 用户需求说明书用自然语言+业务术语描述内容粗略给用户审核用SRS用技术语言+图形描述,内容精细,是开发的直接依据。
- SA把系统按功能层层分解用DFD、ER图等OOA基于用例识别对象用UML图来描述是目前的主流方法。
**应用题参考答案**
- 业务需求:"建立一个在线购物平台提升销售额30%"
- 用户需求:"注册用户可以浏览商品、加入购物车、下单支付"
- 功能需求:"系统应提供商品搜索功能,支持按名称、类别、价格范围筛选"
- 非功能需求:"页面加载时间不超过3秒支持1000人同时在线"
---
## 📘 真题演练
**题目**(教材课后习题):下列哪些是需求获取的技术?(多选)
A. 用户访谈
B. 代码走查
C. 问卷调查
D. 原型法
E. 观察用户工作流程
F. 单元测试
**答案:**
**正确答案A、C、D、E**
B代码走查和F单元测试属于开发/测试阶段的活动,不是需求获取技术。
需求获取的六大技术:联合分析小组、用户访谈、问卷调查、观察工作流程、原型法、文档分析。
---
> 🔗 下一篇:[第3章 用例图](第03章-用例图.md)

View File

@@ -0,0 +1,440 @@
# 第3章 用例图
> **考试重要度**:★★★★★
> **核心内容**:参与者和用例的识别、用例之间的三种关系(包含/扩展/泛化)、用例描述编写、系统边界
---
## 📢 先从生活场景理解用例图
你去银行ATM机取钱整个过程是这样的
```
你(客户)把卡插进去 → 输入密码 → 选择"取款" → 输入金额 → 拿钱 → 取卡
```
在用例图中:
- **你(客户)** = **参与者**Actor—— 系统外部跟系统打交道的人或系统
- **"取款"** = **用例**Use Case—— 系统提供的一项功能
- **取款的详细步骤** = **用例描述**Use Case Description
💬 **一句话**:用例图 = 画出"谁"能用系统"做什么"。
---
## 💡 一、参与者Actor
### 什么是参与者?
> **定义**:系统以外的、需要使用系统或与系统交互的外部实体。
**三类参与者**
| 类型 | 举例 |
|------|------|
| **人** | 客户、图书管理员、系统管理员 |
| **外部设备** | 打印机、传感器、扫描仪 |
| **外部系统** | 短信平台、第三方支付系统、课程目录系统 |
### 怎么找参与者?
🔑 **口诀**:找参与者 = 找"谁在用系统"和"系统跟谁通信"。
> 例:大学图书管理系统中——"读者通过图书管理员借还书籍,系统管理员维护数据"
>
> 参与者有:**读者**、**图书管理员**、**系统管理员**
### 参与者之间的泛化关系
💬 **什么是泛化**= 特殊参与者继承了普通参与者的所有能力,还能做更多事。
> 例:网上购物系统——普通用户只能浏览,注册会员可以浏览+购买。
> 注册会员 = 普通用户的"特殊版",这就是泛化关系。
**泛化的好处**:减少连线数量,简化用例图——特殊参与者自动继承普通参与者的所有关联。
---
## ✍️ 边学边练(一)
**题目**:阅读以下系统描述,找出所有参与者。
"在某大学图书管理系统中,读者通过系统管理员办理借书证。读者分学生和教师。读者借还书籍要通过图书管理员来完成。系统管理员负责借书证维护和图书数据维护等操作。"
**答案:**
参与者有:**图书管理员**、**系统管理员**。
注意:读者不是直接的参与者!因为读者"通过"图书管理员来借还书——他们不直接跟系统交互。但如果系统有自助借还机,读者就可以直接操作,此时读者就是参与者。
⚠️ **易错点**:不是所有提到的人物都是参与者,只有直接跟系统交互的才是。
---
## 💡 二、用例Use Case
### 什么是用例?
> **定义**:参与者可以感受到的、系统提供的一项完整功能。
🔑 **命名规则**:用**动宾结构**——"借书"、"还书"、"查询图书"、"修改密码"。
### 用例的特征
1. **站在系统外部**看到的系统功能(不是内部实现)
2. **总是跟参与者交互**(孤立的操作不算用例)
3. 是一个**行为上相关的步骤序列**(不是一个动作)
4. 用例分析本质上是**功能分解**
### 怎么找用例?
🔑 **口诀**:找用例 = 找"参与者能在这个系统里干什么"。
> 例:大学图书管理系统——读者能"查找图书",图书管理员能"借书""还书""查找图书",系统管理员能"维护借书证""维护图书数据"。
---
## 💡 三、用例之间的关系(重点!必考!)
用例之间有三种关系:**包含**、**扩展**、**泛化**。
### 1. 包含关系(<<include>>
> **含义**:基本用例的行为中**必然**会执行被包含用例的行为。
💬 **比喻**:就像"坐飞机"必然包含"安检"——你想坐飞机就必须过安检,逃不掉。
> 例:网上购物——"在线购物"必然包含"检查信用卡"。
> ATM取款——"取款"必然包含"登录验证"。
**特征**:包含关系是**必须的**、**不可跳过的**。
### 2. 扩展关系(<<extend>>
> **含义**:基本用例的行为中**有条件地**执行扩展用例的行为。
💬 **比喻**:就像"坐飞机"可能扩展"升舱"——不是每次都升舱,只有条件满足时才升。
> 例:图书借阅——"还书"时如果超期,才会扩展执行"缴纳罚款"。
> 例:网上购物——"下单"时如果选了礼品包装,才会扩展执行"礼品包装"。
**特征**:扩展关系是**可选的**、**有条件的**。
### 🔑 包含 vs 扩展 对比(必考!)
| 对比维度 | 包含 <<include>> | 扩展 <<extend>> |
|----------|------------------|-----------------|
| **执行方式** | 必然执行 | 条件执行 |
| **方向** | 基本用例 → 包含用例 | 扩展用例 → 基本用例(箭头指向基本用例) |
| **是否可跳过** | 不可跳过 | 满足条件才执行 |
| **生活比喻** | 坐飞机必安检 | 坐飞机可选升舱 |
⚠️ **画图易错**:包含关系的箭头方向是**基本用例指向包含用例**,扩展关系的箭头方向是**扩展用例指向基本用例**——两个方向相反!
### 3. 泛化关系
> **含义**:子用例继承父用例的行为,并可以覆盖或增加。
💬 **比喻**:就像"支付"是父用例,"微信支付""支付宝支付""银行卡支付"是子用例——它们都是支付,但具体方式不同。
---
## ✍️ 边学边练(二)
**题目**:选课系统描述如下,找出用例和关系。
"学生在登录系统后可以查询课程、注册课程。课程目录从旧系统读取。每学期开始时,系统管理员开放注册。学生选课前必须先查询课程目录。学生完成选课时可以生成课程表,也可以随时生成课程表。系统管理员在登录后可维护学生信息、开放和关闭注册。"
**答案:**
**参与者**:学生、系统管理员、旧课程目录系统
**用例及关系**
- 学生:查询课程、注册课程、生成课程表、登录
- 系统管理员:登录、维护学生信息、开放注册、关闭注册
- 关系:
- "注册课程" 包含 "查询课程"(选课前必须先查课)← 包含关系
- "查询课程"也可能独立存在
- "生成课程表"是"注册课程"的扩展(选课后可生成,也可随时生成)
⚠️ **关键判断**"必须先……"就是包含关系;"可以……"就是扩展关系。
---
## 💡 四、用例描述
### 为什么需要用例描述?
💬 用例图只是"目录"——你看到"取款"这个名字,但不知道取款到底怎么操作。用例描述就是详细的"说明书"。
### 用例描述的模板
| 描述项 | 说明 |
|--------|------|
| **用例名称** | 动宾结构,如"取款" |
| **参与者** | 谁使用这个用例 |
| **前置条件** | 执行前必须满足什么条件 |
| **后置条件** | 执行后系统变成什么状态 |
| **基本操作流程** | 正常情况下的步骤序列 |
| **可选操作流程** | 异常情况或分支的步骤序列 |
| **特殊需求** | 非功能性需求和设计约束 |
### 三种ATM取款的用例描述对比
通过对比你会发现,不同银行的取款流程不一样:
| 步骤 | 农业银行 | 建设银行 | 东莞银行 |
|------|----------|----------|----------|
| 1 | 验证密码 | 输入金额 | 判断是否第一次取款 |
| 2 | 输入金额 | 检查余额 | 若首次→输入金额;否则→验证密码→输入金额 |
| 3 | 检查余额 | 足额→出钞 | 检查余额 |
| 4 | 足额→出钞 | 不足→失败 | 足额→出钞;不足→失败 |
💬 **启示**:同样叫"取款",不同系统的操作流程可能完全不同!所以**用例描述必不可少**。
---
## 💡 五、系统边界
> **定义**:系统边界 = 系统内部和外部的分界线。
>
> - 用例画在边界**里面**(系统能做什么)
> - 参与者画在边界**外面**(谁在使用系统)
🔑 **核心理解**:系统边界决定了谁是参与者。
> 例:基金交易系统
> - 如果**只做交易**(买卖基金)→ 基金管理系统是**外部系统**(参与者)
> - 如果**交易+管理**(买卖+维护基金品种)→ 基金管理系统变成**系统内部功能**
![[Pasted image 20260610205411.png]]
![[Pasted image 20260610205443.png]]
---
## 📌 附录:用例图常用画图符号速查
> 本节把用例图中所有画图符号和标识用字符画的形式汇总一遍画UML图时看着照画就行。
### 1. 参与者Actor—— 两种表示法
**人形符号**(最常用):
```
客户
╱│╲
```
**矩形符号**(协作图或在空间紧张时使用):
```
┌──────────┐
│ :客户 │ ← 冒号 + 类名
└──────────┘
```
### 2. 用例Use Case—— 椭圆
```
╭──────────╮
借书 ╲
│ │
╰──────────╯
```
⚠️ **命名**:椭圆里写**动宾结构**的用例名,如"借书""还书""查询图书"。
### 3. 系统边界 —— 矩形
```
┌─────────── 图书管理系统 ───────────┐
│ │
│ ╭────────╮ │
借书 ╲ ← 用例在内部 │
│ │ │ │
│ ╲
│ ╰────────╯ │
│ │
└─────────────────────────────────────┘
读者 图书管理员
○ ○ ← 参与者在外部
╱│╲ ╱│╲
```
### 4. 参与者与用例的关联 —— 实线
```
读者 ─────────── 借书
○ (椭圆)
╱│╲
```
### 5. 包含关系 <<include>> —— 虚线箭头 + 文字标签
**方向**:基本用例 → 包含用例(箭头指向被包含的那个)。
```
╭──────────╮ ╭──────────╮
注册课程 ╲ 查询课程 ╲
│ │ <<include>> │ │
─ - - - - - ──→ ╲
╰──────────╯ (虚线 + 箭头) ╰──────────╯
(基本用例) (被包含用例)
```
### 6. 扩展关系 <<extend>> —— 虚线箭头 + 文字标签
**方向**:扩展用例 → 基本用例(箭头指向基本用例,与包含**相反**)。
```
╭──────────╮ ╭──────────╮
礼品包装 ╲ 下单 ╲
│ │ <<extend>> │ │
─ - - - - - ──→ ╲
╰──────────╯ (虚线 + 箭头) ╰──────────╯
(扩展用例) (基本用例)
```
⚠️ **易错对比**<<include>> 和 <<extend>> 箭头方向**相反**,考试常考。
### 7. 用例之间的泛化关系 —— 实线 + 空心三角形
**方向**:子用例 → 父用例(子用例继承父用例的行为)。
```
╭──────────╮ ╭──────────╮
微信支付 ╲ 支付 ╲
│ │ ─ ─ ─▷ │ │
(空心三角) ╲
╰──────────╯ ╰──────────╯
(子用例) (父用例)
```
### 8. 参与者之间的泛化关系 —— 实线 + 空心三角形
**方向**:特殊参与者 → 一般参与者(特殊继承普通的能力)。
```
╭─────╮
│ 钻石会员 │ (特殊)
│ /│\ │ ─ ─ ─▷ 普通用户
│ / │ \ │ (一般)
╰───────╯
```
### 9. 完整用例图示例
把上面所有符号拼在一起画出来的样子:
```
读者
╱│╲
┌──── 图书管理系统 ──────────────────────┐
│ │
│ ╭──────╮ │
借书 ╲ ←──── <<include>> ────╮ │
││ │ │ │
│ ╲ │ │
│ ╰──────╯ │ │
│ ╭──────╮ │ │
还书 ╲ ←──── <<extend>> ────╮ │
││ │ │ │
│ ╲ │ │
│ ╰──────╯ │ │
│ │ │
│ ╭──────╮ │ │
缴纳 ╲ ←────────┘ │ │
││ 罚款 │ │ │
│ ╲ │ │
│ ╰──────╯ │ │
│ ╭──────╮ ── <<include>> ──→ │ │
查询 ╲ │ │
││ 图书 │ │ │
│ ╲ │ │
│ ╰──────╯ │ │
│ │ │
└──────────────────────────────────┘ │
管理员 │
○ │
╱│╲ │
╲ │
│ (借书/还书关联)
```
🔑 **一句话记忆口诀**:边界矩形圈住用例,参与者画在边界外;包含扩展都是虚线箭头,方向相反要分清;泛化用空心三角,子指向父别搞错。
---
## ✍️ 边学边练(三)
**题目**:判断以下说法是否正确。
1. 包含用例必然被执行,扩展用例条件被执行。
2. 包含关系的箭头从包含用例指向基本用例。
3. 系统边界决定了谁是参与者。
4. 用例描述可有可无,有图就够了。
**答案:**
- ① ✅ 正确。包含=必然,扩展=条件。
- ② ❌ 错误。包含关系箭头从**基本用例指向包含用例**(基本用例"使用"包含用例)。扩展关系箭头从**扩展用例指向基本用例**。
- ③ ✅ 正确。边界划在哪里,决定了谁是"外面的"参与者。
- ④ ❌ 错误。没有描述的用例就像只有目录的书——只知道标题不知道内容。
---
## 📝 章末自测
**1. 填空题**
- 参与者分三类:( ______ )、外部设备、( _____
- 用例之间的关系有三种:( ____ )、( _____ )、( ____
- 在用例图中,用例画在系统边界的( ____ )(里面/外面)
**2. 判断题**(对还是错?)
- ( ) 一个参与者只能是一个人
- ( ) 包含关系表示可选的功能
- ( ) 扩展关系的箭头指向基本用例
- ( ) 系统边界决定了谁是参与者
- ( ) 用例描述就是用于说明用例的操作流程
**3. 简答题**
- 简述包含关系和扩展关系的区别。
- 参与者之间的泛化关系有什么作用?
**答案:**
**填空题**:人、外部系统;包含关系、扩展关系、泛化关系;里面
**判断题**:❌(也可以是外部系统) ❌(包含=必然) ✅ ✅ ✅
**简答题**
- 包含关系:基本用例必然执行包含用例(如取款必登录);扩展关系:基本用例有条件执行扩展用例(如还书超期才罚款)。箭头方向也不同,包含箭头是基本→包含,扩展箭头是扩展→基本。
- 泛化关系让特殊参与者继承普通参与者的所有关联,减少连线数量,简化模型。
---
## 📘 真题演练
**题目**:为"网上酒店预订系统"画用例图。需求:客户可浏览酒店、预订房间、取消预订、查看订单。管理员可管理酒店信息、管理房间信息、处理预订。客户和管理员都需要登录后才能操作。
**答案:**
**参与者**:客户、管理员
**用例**
- 客户:浏览酒店、预订房间、取消预订、查看订单、登录
- 管理员:管理酒店信息、管理房间信息、处理预订、登录
**关系**
- "浏览酒店"不需要登录(独立用例)
- "预订房间"包含"登录"(预订前必须登录)
- "管理酒店信息"包含"登录"
- 其他需要登录的用例同理
⚠️ **关键**:登录通常作为包含用例,因为它是一个共用的强制性步骤。
---
> 🔗 上一篇:[第1章 需求工程](第01章-需求工程.md) | 下一篇:[第4章 类图与对象图](第04章-类图与对象图.md)

View File

@@ -0,0 +1,475 @@
# 第4章 类图与对象图
> **考试重要度**:★★★★★
> **核心内容**:类与对象的识别、六大类关系、抽象类与接口、边界类/控制类/实体类
---
## 📢 从生活中理解类和对象
💬 **类 = 模板,对象 = 具体的东西。**
| 概念 | 生活例子 | 代码例子 |
|------|----------|----------|
| **类** | "汽车"这个类别 | `class Car` |
| **对象** | 你家楼下停的那辆红色宝马 | `Car myCar = new Car()` |
| **属性** | 颜色、车牌号、排量 | `color`, `plateNumber` |
| **操作** | 启动、加速、刹车 | `start()`, `accelerate()` |
> 例:银行的"账户"类有属性姓名、密码、余额和操作查询余额、存款、取款。张三的账户就是一个具体对象余额是5000元。
---
## 💡 一、类的三格表示法
```
┌──────────────────────┐
│ 类名 │ ← 第一格:类名
├──────────────────────┤
│ -name: String │ ← 第二格:属性
│ -age: int │
│ +count: int │
├──────────────────────┤
│ +getName(): String │ ← 第三格:操作(方法)
│ +setAge(a: int) │
└──────────────────────┘
```
### 属性语法
```
[可见性] 属性名 [:类型] [=初始值] [{约束}]
```
### 可见性符号
| 符号 | 名称 | 含义 |
|------|------|------|
| `+` | Public公有 | 谁都能访问 |
| `-` | Private私有 | 只能类内部访问 |
| `#` | Protected受保护 | 类内部+子类能访问 |
---
## ✍️ 边学边练(一)
**题目**银行账户类Account有属性账号(私有)、密码(私有)、余额(私有)、利率(公有)。请用UML类图的三格表示法写出。
**答案:**
```
┌──────────────────────┐
│ Account │
├──────────────────────┤
│ -accountNo: String │
│ -password: String │
│ -balance: double │
│ +interestRate: float│
├──────────────────────┤
│ +getBalance():double│
│ +deposit(amt) │
│ +withdraw(amt) │
└──────────────────────┘
```
---
## 💡 二、类之间的六大关系(重中之重!必考!)
### 1. 关联关系Association—— "认识/拥有"
> **含义**:一个类的属性类型是另一个类。这是最基础的关系。
💬 **比喻**:员工"属于"某个部门——Employee类中有一个Department类型的属性。
**关联关系的子类型**
| 子类型 | 说明 | 生存期 | 画法 |
|--------|------|--------|------|
| **普通关联** | 平等关系 | 各自独立 | 实线 |
| **聚合Aggregation** | 整体-部分,弱关系 | 部分可独立存在 | 空心菱形 |
| **组合Composition** | 整体-部分,强关系 | 部分随整体消亡 | 实心菱形 |
💬 **聚合 vs 组合**
- 聚合:学校由学生组成,学校解散了,**学生还在**。
- 组合:汽车由发动机组成,汽车报废了,**发动机也没意义了**。
### 2. 依赖关系Dependency—— "临时使用"
> **含义**:一个类的方法的参数/返回值/局部变量用了另一个类。
💬 **比喻**:你去商店买东西——你跟商店的关系只在买东西那一刻存在,买完就没关系了。
### 3. 泛化关系Generalization—— "是……的一种"
> **含义**:子类继承父类的属性和方法。
💬 **比喻**:狗是动物的一种——狗继承了动物的所有特征,还有自己特有的"汪汪叫"。
### 4. 实现关系Realization—— "履行接口约定"
> **含义**:类实现了接口中定义的所有方法。
### 关联 vs 依赖 对比
| 维度 | 关联 | 依赖 |
|------|------|------|
| **强度** | 强,长期稳定 | 弱,临时短暂 |
| **代码体现** | 属性类型是另一个类 | 方法参数/局部变量用了另一个类 |
| **生命周期** | 对象存在就有关系 | 方法调用结束关系就结束 |
| **画法** | 实线 | 虚线箭头 |
---
## ✍️ 边学边练(二)
**题目**:判断以下场景属于什么关系。
1. 飞机由机翼、发动机、机身组成。(飞机-机翼)
2. 医生在医院工作。(医生-医院)
3. 学生是人。(学生-人)
4. 程序员写代码时用到开发工具。(程序员-开发工具)
**答案:**
1. **组合关系**(实心菱形)—— 机翼不能脱离飞机独立存在
2. **关联关系**(普通关联)—— 医生有"所属医院"这个属性
3. **泛化关系**(继承)—— 学生是人的子类
4. **依赖关系**(虚线箭头)—— 程序员"写代码"这个方法用到了开发工具,但不是长期持有
⚠️ **易错点**:聚合和组合都表示"整体-部分",区别在于部分能否独立存在。能独立=聚合,不能独立=组合。
---
## 💡 三、关联关系的重要概念
### 多重性
| 表示法 | 含义 |
|--------|------|
| `1` | 恰好1个 |
| `0..1` | 0个或1个 |
| `0..*``*` | 0个或多个 |
| `1..*` | 至少1个 |
| `n..m` | n到m个 |
> 例:一个学生选**0..\***门课,一门课被**1..\***个学生选。
### 关联类
> 当一个属性放在哪个类都不合适时,就用关联类。
💬 例:员工和公司之间有个"合同"——合同有"工资"属性。工资既不是员工的固有属性(换公司会变),也不是公司的固有属性。所以"合同"是一个关联类。
### 限定关联
> 用限定符把多对多变成一对多,提高查询效率。
💬 例:一个人可以在多家银行开户(多对多)。但如果限定"在某家银行",就变成一对多了。
---
## 💡 四、抽象类 vs 接口
| 维度 | 抽象类 | 接口 |
|------|--------|------|
| **属性** | 可以有 | 不能有 |
| **方法实现** | 部分方法有实现 | 所有方法都没有实现 |
| **关系** | 子类继承(泛化) | 类实现(实现关系) |
| **多重性** | 只能继承一个 | 可以实现多个 |
| **关键词** | `abstract class` | `interface` |
💬 **比喻**:抽象类像"半成品家具"(有些部分做好了,有些需要你自己完成);接口像"插座标准"(只规定了插孔形状和电压,具体怎么发电不管)。
---
## 💡 五、版型:边界类、控制类、实体类
这是MVC模式的UML体现期中考试经常考
| 版型 | 职责 | 常见形式 | 对应MVC |
| ---------------------- | ------ | --------- | ---------- |
| **边界类** `<<boundary>>` | 与外界交互 | 窗口、对话框、报表 | View |
| **控制类** `<<control>>` | 协调业务逻辑 | 处理业务规则 | Controller |
| **实体类** `<<entity>>` | 持久化数据 | 数据库表对应的类 | Model |
🔑 **协作关系**:边界类接收用户输入 → 控制类处理业务逻辑 → 实体类存取数据。
---
## 📌 附录:类图常用画图符号速查
> 这一节把类图中所有的关系符号、接口、抽象类、版型、对象图等所有画图元素用字符画列出来,画类图时直接照搬即可。
### 1. 关联关系Association—— 实线(可带多重性)
**普通关联**(双向带多重性):
```
┌────────┐ 1 0..* ┌────────┐
│ 老师 │ ────────────────── │ 学生 │
└────────┘ └────────┘
```
**自关联**(一个类关联到自己):
```
┌────────┐
│ 员工 │
│ │
│ 领导 │◀──┐
└────────┘ │
│ │
└─────┘
```
### 2. 聚合关系Aggregation—— 实线 + 空心菱形 ◇
> 部分可脱离整体独立存在。
```
┌────────┐ ┌────────┐
│ 班级 │ ───────────── │ 学生 │
└────────┘ └────────┘
(整体) (部分,可独立)
💬 学校没了,学生还在 —— 所以是空心菱形
```
### 3. 组合关系Composition—— 实线 + 实心菱形 ◆
> 部分不能脱离整体独立存在。
```
┌────────┐ ┌────────┐
│ 汽车 │ ───────────── │ 发动机 │
└────────┘ └────────┘
(整体) (部分,离不开整体)
💬 汽车报废了,发动机也没意义了 —— 所以是实心菱形
```
### 4. 依赖关系Dependency—— 虚线 + 开放箭头
```
┌────────┐ ┌────────┐
│ 司机 │ ─ ─ ─ ─ ─ ─ ─⇨ │ 汽车 │
└────────┘ └────────┘
(使用者) (被使用者)
(虚线 + 开放箭头)
```
### 5. 泛化关系Generalization—— 实线 + 空心三角
**方向**:子类 → 父类(空心三角指向父类)。
```
┌────────┐ ┌────────┐
│ 狗 │ ───────────── │ 动物 │
└────────┘ └────────┘
(子类) (父类)
```
### 6. 实现关系Realization—— 虚线 + 空心三角
**方向**:实现类 → 接口(空心三角指向接口)。
```
┌────────┐ ┌──────────────┐
│ 鸟 │ ─ ─ ─ ─ ─ ─ ─ │<<interface>>│
└────────┘ │ 飞行 │
(实现类) └──────────────┘
(接口)
```
### 7. 接口的两种画法
**普通矩形画法**(在类图中更常见):
```
┌──────────────────┐
│ <<interface>> │ ← 关键字标识
│ 飞行 │ ← 接口名
├──────────────────┤
│ +起飞(): void │ ← 只有声明,没有实现
│ +降落(): void │
└──────────────────┘
```
**棒棒糖表示法**(简化版,常在组件图中使用):
```
┌────────┐ ┌────────┐
│ 鸟 │●─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ 飞行 │ (棒棒糖+连接线)
└────────┘ └────────┘
(实现类) (接口)
```
### 8. 抽象类与抽象方法
> **画法**:抽象类**类名用斜体**、抽象方法**方法名用斜体**。在字符画里用 `<<abstract>>` 标识或加文字说明。
```
┌────────────┐
│ 动物 │ ← 实际画图时类名用斜体
├────────────┤
│ │
├────────────┤
│ 移动() │ ← 实际画图时方法名用斜体
│ 叫() │
└────────────┘
{abstract} ← 标注方式(实际画图用斜体)
```
### 9. 版型Stereotype的画法
**边界类**
```
┌────────────────┐
│ <<boundary>> │ ← 写在类名上方
│ 登录页面 │
├────────────────┤
│ -用户名:String │
│ -密码:String │
├────────────────┤
│ +提交():void │
└────────────────┘
```
**控制类**
```
┌────────────────┐
│ <<control>> │
│ 订单处理 │
├────────────────┤
│ │
├────────────────┤
│ +处理订单() │
│ +检查库存() │
└────────────────┘
```
**实体类**
```
┌────────────────┐
│ <<entity>> │
│ 订单 │
├────────────────┤
│ -订单号:String│
│ -金额:double │
├────────────────┤
│ +保存() │
│ +查询() │
└────────────────┘
```
### 10. 对象图的画法
> 对象名格式:`对象名:类名`(对象名和类名下加**下划线**),属性有具体值。
```
┌─────────────────┐
│ 张三:员工 │ ← 对象名:类名,下划线
├─────────────────┤
│ 员工号 = "E001" │ ← 属性=值
│ 姓名 = "张三" │
│ 年龄 = 28 │
└─────────────────┘
```
**对象图与类图对比**
```
类图(描述规则) 对象图(描述实例)
┌──────────┐ ┌────────────────┐
│ 员工 │ │ 张三:员工 │
├──────────┤ ├────────────────┤
│ -员工号 │ │ 员工号="E001" │
│ -姓名 │ ──> │ 姓名="张三" │
│ -年龄 │ │ 年龄=28 │
├──────────┤ └────────────────┘
│ +查询() │
└──────────┘
```
### 11. 关联类的画法
> 关联类挂在关联线中间,用虚线连到关联线上。
```
┌────────┐ ┌────────┐
│ 员工 │ ─ ─ ─ ─ ─ ─ ─ │ 公司 │
└────────┘ │ └────────┘
┌────────┐
│ 合同 │ ← 关联类(虚线连到关联线上)
├────────┤
│ -工资 │
│ -合同期│
└────────┘
```
🔑 **一句话记忆口诀**:实线实箭是关联,空心菱形是聚合,实心菱形是组合,虚线开放箭头是依赖;实线空三角是泛化(继承),虚线空三角是实现(接口)。
---
## ✍️ 边学边练(三)
**题目**:在线购物系统中,"用户"通过"购物页面"下单,系统"订单处理"模块检查库存后,更新"订单"数据和"库存"数据。请指出各属于哪种版型。
**答案:**
- 购物页面 → **边界类**(与用户交互)
- 订单处理模块 → **控制类**(协调业务逻辑)
- 订单、库存 → **实体类**(持久化的数据)
完整流程:边界类("购物页面") → 控制类("订单处理") → 实体类("订单""库存")
---
## 💡 六、对象图
> **对象图 = 类图的"截图"**。类图描述通用规则,对象图描述某一时刻的具体情况。
| 类图 | 对象图 |
|------|--------|
| 三个格子(类名+属性+操作) | 两个格子(对象名:类名 + 属性值) |
| 描述所有可能的情况 | 描述某一个时刻的快照 |
| 属性定义特征(如"姓名: String" | 属性有具体值(如"姓名 = 张三" |
💬 **比喻**:类图像"菜单"(描述菜的做法),对象图像"上桌的菜"(一份具体的菜)。
---
## 📝 章末自测
**1. 填空题**
- 聚合关系中,整体不存在了,部分( ___ )存在。(能/不能)
- 组合关系中,整体不存在了,部分( ___ )存在。(能/不能)
- 边界类、控制类、实体类分别对应MVC中的 _____ )、( _____ )、( ___
**2. 判断题**
- ( ) 依赖关系比关联关系更弱
- ( ) 接口可以有属性
- ( ) 抽象类可以被实例化
- ( ) 对象图是类图的实例
- ( ) 一个类只能继承一个抽象类,但可以实现多个接口
**3. 分析题**
- 职工类Employee包含属性empcode、name、address、birthday。Address类包含houseNumber、streetNumber、city、zipcode。分析两个类之间的关系。
**答案:**
**填空题**能、不能、View、Controller、Model
**判断题**:✅ ❌(接口无属性) ❌(抽象类不能实例化) ✅ ✅
**分析题****关联关系**。因为Employee类中有一个属性address其类型是Address类。这是一个长期稳定的结构关系。多重性Employee端1Address端0..*(一个地址可以被多个员工使用)。
---
> 🔗 上一篇:[第3章 用例图](第03章-用例图.md) | 下一篇:[第5章 顺序图与协作图](第05章-顺序图与协作图.md)

View File

@@ -0,0 +1,385 @@
# 第5章 顺序图与协作图
> **考试重要度**:★★★★
> **核心内容**顺序图的四个核心元素、六种消息类型、调用消息vs异步消息、顺序图与协作图的对比
---
## 📢 从打电话理解交互图
💬 你打电话给朋友借钱,整个对话过程是这样的:
```
你 → 拨号 → 朋友接电话 → 你说"借我500" → 朋友说"好" → 你挂电话
```
这就是一个**交互过程**——两个对象之间按时间顺序传递消息。在UML中我们用**顺序图**和**协作图**来描述这个过程。
---
## 💡 一、顺序图的四个核心元素
```
┌─────────────────────────────────────────────┐
│ 对象 生命线 控制焦点(激活期) │
│ ┌───┐ │ ┌──┐ │
│ │obj│ │ │ │ │
│ └─┬─┘ │ └──┘ │
│ │- - - - - │- - - - - - - - - - - │
│ │ │ 消息→ │
│ │ │ ┌──┐ │
│ │ │ │ │ │
│ │ │ └──┘ │
└─────────────────────────────────────────────┘
```
| 元素 | 说明 | 画法 |
|------|------|------|
| **对象** | 类的实例,参与交互的实体 | 矩形,顶部放置 |
| **生命线** | 对象存在的时间线 | 从对象向下延伸的虚线 |
| **控制焦点**(激活期) | 对象正在执行操作的时间段 | 生命线上的细长矩形条 |
| **消息** | 对象之间的一次通信 | 带箭头的直线 |
---
## 💡 二、消息的语法格式
消息的完整格式:
```
[前置条件] [警戒条件] [序号] [返回值:=] 消息名([参数列表])
```
例子:
```
2: display(x, y) → 简单消息序号2
1.3.1: p := find(specs) → 嵌套消息,有返回值
[x<0] 4: invert(x, color) → 条件消息
3.1*: update() → 循环消息
```
### 消息序号的含义
- `1, 2, 3` — 顺序发送的消息
- `1.1, 1.2, 1.3` — 消息1内部的嵌套调用1.1必须在1完成之前完成
- `A1, B1` — 并发线程中的消息
---
## 💡 三、六种消息类型
| 消息类型 | 说明 | 画法 |
|----------|------|------|
| **调用消息** (同步) | 发送者等待接收者完成才继续 | 实线实心箭头 → |
| **异步消息** | 发送者不等待,继续执行 | 实线开放箭头 ⇢ |
| **返回消息** | 从调用返回 | 虚线开放箭头 ⇢ |
| **反身消息** | 发给自己 | 绕回自己的箭头 |
| **阻止消息** | 接收者不能立即接收就放弃 | 特殊标记 |
| **超时消息** | 等待指定时间,超时就放弃 | 特殊标记 |
### 📌 消息类型的画法速查
> 这一节把六种消息类型的**实际画法**用字符画的形式画出来,光看箭头符号记不住的话,照着画就行。
#### ① 调用消息(同步)—— 实线 + 实心三角箭头
```
┌───┐ ┌───┐
│ A │ ──────────────────▶│ B │ ← 实线 + 实心三角
└───┘ └───┘
同步等B做完再回来
```
#### ② 异步消息 —— 实线 + 开放箭头V形
```
┌───┐ ┌───┐
│ A │ ─────────────────⇨ │ B │ ← 实线 + 开放箭头
└───┘ └───┘
异步:发完就接着干自己的事
```
#### ③ 返回消息 —— 虚线 + 开放箭头
```
┌───┐ ┌───┐
│ A │ ◀─ ─ ─ ─ ─ ─ ─ ─ ─ │ B │ ← 虚线 + 开放箭头
└───┘ └───┘
返回值(可省略不画)
```
#### ④ 反身消息 —— 自己绕回来
```
┌───┐
│ A │ ───┐
└───┘ │
│ │
◀─────┘
(即"对象调用自己的方法"
```
#### ⑤ 阻止消息 —— 实线 + 叉 ✕
> 接收方当时忙,**直接放弃**这次调用。
```
┌───┐ ┌───┐
│ A │ ─────────────────╳ │ B │ ← 实线 + 叉
└───┘ └───┘
B没空A立刻放弃不等
```
#### ⑥ 超时消息 —— 实线 + 倒三角 ⏳
> 等待指定时间,**超时就放弃**。
```
┌───┐ ┌───┐
│ A │ ─────────────────⏳ │ B │ ← 实线 + 倒三角
└───┘ └───┘
等一段时间后超时
```
### 📌 完整顺序图示例
把所有消息类型都画在一张图里看效果:
```
客户 ATM界面 账户
┌───┐ ┌───┐ ┌───┐
│ │ │ │ │ │
╱│╲ │ ╱│╲ │ ╱│╲ │
╲ │ ╲ │ ╲ │
┌───┐ ┌───┐ ┌───┐
│ │ │ │ │ │
│ │ 1: 取款(500) │ │ │ │ ← ① 调用消息
│ ├──────────────▶│ │ │ │
│ │ │ │ 2: 查询余额() │ │ ← ① 调用消息
│ │ │ ├───────────────▶│ │
│ │ │ │ │ │
│ │ │ │ ◀─ 3: 余额 ─── │ │ ← ③ 返回消息
│ │ │ │ │ │
│ │ │ │ 4: 扣款(500) │ │ ← ① 调用消息
│ │ │ ├───────────────▶│ │
│ │ │ │ │ │
│ │ 5: 出钞 │ │ │ │ ← ② 异步消息
│ │◀─ ─ ─ ─ ─ ─ ─│ │ │ │
│ │ │ │ │ │
```
### 📌 组合片段Combined Fragment速查
> 当顺序图比较复杂时,可以用**框选区域**的方式来表达条件、循环、并行等逻辑。
```
┌────────────── alt: 余额判断 ──────────────┐
│ │
│ │ 条件A: │
│ │ 4.1: 扣款(amount) ──▶ │
│ │ │
├────────────────────────────────────────────┤
│ │
│ │ 条件B: │
│ │ 4.2: 显示"余额不足" ──▶ │
│ │
└────────────────────────────────────────────┘
```
常用组合片段关键字:
| 关键字 | 含义 | 用途 |
|--------|------|------|
| `alt` | 抉择(多选一) | 相当于 if-else |
| `opt` | 可选(满足才执行) | 相当于单分支 if |
| `loop` | 循环 | 相当于 for/while |
| `par` | 并行 | 多个事件流同时进行 |
| `neg` | 非法 | 描述不允许发生的场景 |
| `critical` | 关键 | 必须原子执行的区域 |
---
### 📌 协作图Communication Diagram的画法
> 协作图 = 顺序图的"空间版"——**没有生命线**,但消息必须**带完整序号**。
```
1: 输入金额
客户 ──────────────▶ ATM界面
○ │
╱│╲ │ 2: 查询余额
╲ ▼
账户
╱│╲
│ 3: 返回余额
◀───── 4.1*: 出钞 ─────┘
(出钞多次循环)
```
**协作图的关键特征**
- 对象之间的**连线**(关联)作为消息传递的路径
- 消息的**前缀序号**必须完整(`1`, `1.1`, `1.1.1`
- `{new}` 标签表示对象在交互中被创建
- `{destroy}` 标签表示对象在交互中被销毁
```
┌──────────┐ ┌──────────┐
│ :Order │ │ :Payment │
│{new} │ 1: 创建支付 │ │
└──────────┘ ────────────────▶ └──────────┘
│ {destroy}
(被销毁)
```
🔑 **一句话记忆口诀**实心三角是同步开放箭头是异步返回用虚线开放箭头反身消息自己绕alt/loop/par 框选区域,条件循环并行都能搞。
---
## 🔑 调用消息 vs 异步消息(必考!)
| 对比维度 | 调用消息 | 异步消息 |
|----------|----------|----------|
| **发送者行为** | 发出后**停下来等** | 发出后**继续干活** |
| **控制焦点** | 发送者出现等待(重叠矩形条) | 发送者不等待 |
| **典型场景** | 查询数据库(必须等结果) | 写日志文件(可以后台进行) |
| **返回消息** | 必有返回,可以省略不画 | 如果是过程调用必有返回 |
💬 **比喻**
- 调用消息像**打电话**——你说一句,等对方回一句。
- 异步消息像**发微信**——你发一条,继续干自己的事,对方看到再回。
---
## 💡 四、顺序图的两种形式
| 形式 | 说明 |
|------|------|
| **一般形式** | 包含条件、分支、循环,描述所有可能的场景 |
| **实例形式** | 只有一个具体的场景,没有任何分支和循环 |
💬 例:取款的一般形式包含"余额够"和"余额不够"两个分支;而某次具体取款(余额够)就是实例形式。
### 条件消息和循环消息的表达
**两种方法**
1. 在消息上直接标注:`[x>0] 3: doSomething()``2.1*: update()`
2. 使用交互架构(框选一个区域,标注`loop``alt`
---
## 💡 五、协作图
### 协作图 vs 顺序图
| 维度 | 顺序图 | 协作图 |
|------|--------|--------|
| **强调** | **时间顺序** | **空间位置关系** |
| **生命线** | 有(从上到下) | 无 |
| **控制焦点** | 有(矩形条) | 无 |
| **消息序号** | 通常简化 | 必须完整标注 |
| **多对象** | 不直观 | 可以表达 |
| **主动对象** | 不直观 | 可以表达 |
🔑 **核心区别**:顺序图强调"什么时间谁调用了谁",协作图强调"谁跟谁有连接关系"。
### 协作图的特殊元素
| 元素 | 说明 |
|------|------|
| **多对象** | 代表一组对象,发给它的消息是发给整个集合 |
| **主动对象** | 拥有自己控制线程的对象,可以主动发起消息 |
| **{new}** | 标记对象在交互中被创建 |
| **{destroy}** | 标记对象在交互中被销毁 |
---
## ✍️ 边学边练(一)
**题目**ATM取款的基本流程如下请画出分析阶段的顺序图。
1. 用户输入取款金额
2. 系统判断账户余额是否足额
3. 若足额,则出钞并修改账户余额
4. 若不足额,则取款失败
**答案:**
顺序图包含对象:`:客户``:ATM界面``:账户`
消息序列:
```
1. 客户 → ATM界面: 输入金额(amount)
2. ATM界面 → 账户: 查询余额()
3. 账户 → ATM界面: 返回余额(balance)
4. ATM界面 → 自己: [balance>=amount]判断
5a. ATM界面 → 账户: 扣款(amount) [金额足够]
5b. ATM界面 → 客户: 显示"余额不足" [金额不足]
```
⚠️ 关键步骤4的判断是ATM界面对象自己的处理用反身消息或不画都可以。
---
## ✍️ 边学边练(二)
**题目**:判断以下场景应该用调用消息还是异步消息。
1. 用户点击"登录"按钮,系统验证用户名密码
2. 用户上传文件后,系统后台写入日志
3. 用户查询订单列表,系统返回查询结果
4. 系统给所有订阅用户发送邮件通知
**答案:**
1. **调用消息(同步)**—— 必须等验证结果,用户才能进入下一步
2. **异步消息**—— 写日志不阻塞用户操作
3. **调用消息(同步)**—— 必须等返回结果才能显示
4. **异步消息**—— 发邮件是批量后台操作,不需要等待
🔑 **判断标准**:发送者是否**必须等待**结果才能继续。必须等=调用消息,不必等=异步消息。
---
## 💡 六、交互建模的步骤
1. 根据一个用例的用例描述,找出**基本事件流**和**可选事件流**
2. 确定参与交互的**对象**(参考类图)
3. 按事件流的**先后次序**确定消息发送次序
4. 标注需要**创建**和**撤销**的对象
5. 处理**循环**和**分支**消息
---
## 📝 章末自测
**1. 填空题**
- 顺序图的四个核心元素是:( ____ )、( ____ )、( ____ )、( ___ _
- 发送后等待返回的消息叫( ____ )消息,发送后继续执行的消息叫( ____ )消息
- 顺序图强调( _____ )顺序,协作图强调( ____ )关系
**2. 判断题**
- ( ) 调用消息的返回消息必须画出来
- ( ) 顺序图可以表示对象的创建和销毁
- ( ) 协作图中消息序号1.1表示它在消息1完成后才开始
**3. 简答题**
- 顺序图和协作图各有什么优势和适用场景?
**答案:**
**填空题**:对象、生命线、控制焦点、消息;调用(同步)、异步;时间、空间位置
**判断题**
- ❌ 调用消息的返回消息可以省略不画(隐式)
- ✅ 对象顶部放置={new},虚线末端×={destroy}
- ❌ 消息1.1在消息1**完成之前**就必须完成(嵌套含义)
**简答题**
- 顺序图:适合展示按时间顺序发生的消息交互,直观易懂,适合分析单个用例的执行流程
- 协作图:适合展示对象之间的静态连接关系,能表达多对象和并发,适合整体架构分析
---
> 🔗 上一篇:[第4章 类图与对象图](第04章-类图与对象图.md) | 下一篇:[第6章 状态图与活动图](第06章-状态图与活动图.md)

View File

@@ -0,0 +1,434 @@
# 第6章 状态图与活动图
> **考试重要度**:★★★★★
> **核心内容**:状态图的组成(状态/转移/事件)、四种事件类型、活动图元素(泳道/分支/分叉汇合、状态vs活动的区别
---
## 📢 从手机理解状态图和活动图
💬 你的手机有以下**状态**:闲置 → 解锁 → 使用中 → 锁屏 → 闲置。
每个状态之间的切换需要**事件**触发:点击屏幕、输入密码、按电源键……
这就是**状态图**——描述**一个对象**在生命周期内的状态变化。
而**活动图**描述的是**一个流程**:比如"打电话"这个活动——打开拨号盘 → 输入号码 → 点击拨号 → 通话 → 挂断。这其中可能涉及多个对象。
---
## 💡 一、状态图的核心元素
### 状态图三要素
```
┌──────────┐ 事件[条件]/动作 ┌──────────┐
│ 状态A │ ─────────────────→ │ 状态B │
└──────────┘ └──────────┘
```
| 要素 | 说明 |
|------|------|
| **状态** | 对象在某个时刻所处的条件或状况 |
| **转移** | 从一个状态到另一个状态的变化 |
| **事件** | 触发状态转移的原因 |
### 状态的组成
```
┌────────────────────────┐
│ 状态名 │
├────────────────────────┤
│ entry / 入口动作 │
│ exit / 出口动作 │
│ do / 持续活动 │
│ 内部转移(不离开状态) │
└────────────────────────┘
```
### 组合状态和历史状态
💬 **组合状态**:一个大状态里面还有小状态的变化过程。
> 例:汽车"行驶"状态里面还有子状态:加速、匀速、减速。
💬 **历史状态**:记住离开组合状态时处于哪个子状态,回来后可以接着来。
> 例:数据备份——中途被打断,恢复后可以继续从断点备份。
---
## 💡 二、四种事件类型
| 事件类型 | 含义 | 举例 |
|----------|------|------|
| **调用事件** | 一个方法的调用 | `借书()` → 借书证从"可借"变为"不可借" |
| **信号事件** | 一个异步发送的信号实体 | 遥控器发出"Play"信号 → CD机进入"播放"状态 |
| **变化事件** | 布尔表达式值发生变化 | 温度>100℃ → 锅炉进入"报警"状态 |
| **时间事件** | 到达某个时间点或时间段 | 30秒超时 → 从"拨号"回到"就绪" |
### 🔑 调用事件 vs 信号事件
| 对比 | 调用事件 | 信号事件 |
|------|----------|----------|
| **本质** | 调用一个方法 | 发送一个信号对象 |
| **发送方** | 可以是自己或其他对象 | 只能是其他对象 |
| **特点** | 可扩展性弱 | 信号类可泛化,扩展性强 |
💬 例CD唱机——如果各种遥控信号作为遥控器的属性变化事件增加新信号就要修改遥控器类。如果把遥控信号建模为信号类信号事件增加新信号只需新增子类不用改遥控器。
---
## ✍️ 边学边练(一)
**题目**:画出"图书"对象的状态图。
需求:新书购买后需编码才能入库。入库后可借出。借出的书不能被再借出。还书后可再借出。图书破损或过时必须下架,下架后不能再借出。
**答案:**
**状态**:未编码 → 可借(在库) → 已借出 → 可借(在库) → 已下架
**转移**
- 未编码 → 可借:`编码()`
- 可借 → 已借出:`借出()`
- 已借出 → 可借:`还书()`
- 可借 → 已下架:`下架()` [破损或过时]
- 已借出 → 已下架:`下架()` [破损或过时]
⚠️ 注意:状态图中有两个状态必须有"下架"转移(从可借和已借出都可以下架)。
---
## 💡 三、活动图的核心元素
### 活动图的基本元素
| 元素 | 说明 | 画法 |
|------|------|------|
| **活动** | 一个执行步骤 | 圆角矩形 |
| **起点** | 流程的开始 | 实心圆 ● |
| **终点** | 流程的结束 | 圆圈加实心圆 ⊙ |
| **分支** | 根据条件选择路径 | 菱形 ◇ |
| **分叉/汇合** | 并发执行的开始/结束 | 粗横线 |
| **泳道** | 标明活动由谁负责 | 纵向分区 |
| **对象流** | 活动之间传递的对象 | 带箭头的虚线 |
### 📌 活动图各元素的画法速查
> 这一节把活动图中**所有画图元素**用字符画列出来,画活动图直接照搬即可。
#### ① 起点 —— 实心圆 ●
```
```
#### ② 终点 —— 圆圈加实心圆 ⊙(也称"牛眼"
```
```
#### ③ 活动Activity—— 圆角矩形
```
╭───────────╮
│ 登录验证 │ ← 文字描述这一步做什么
╰───────────╯
```
#### ④ 转移箭头 —— 实线 + 开放箭头
```
╭───────────╮
│ 活动 A │
╰─────┬─────╯
⇨ 实线 + 开放箭头(类似异步消息)
╭─────┴─────╮
│ 活动 B │
╰───────────╯
```
#### ⑤ 分支Decision—— 菱形 ◇ + 监护条件
```
╭───────────╮
│ 活动 A │
╰─────┬─────╯
◇ ← 菱形(决策点)
[是] ╲[否]
╭─────╮ ╭─────╮
│ 活动B │ │ 活动C │
╰─────╯ ╰─────╯
◇ ← 合并点(多个分支汇合)
╭─────┴─────╮
│ 活动 D │
╰───────────╯
```
#### ⑥ 分叉Fork/ 汇合Join—— 粗横线
> **分叉**:一条路径分成多条并发执行。
> **汇合**:多条并发路径汇合成一条。
```
╭───────────╮
│ 活动 A │
╰─────┬─────╯
━━━━━━━━━━ ← 粗横线(分叉点)
│ │
⇨ ⇨
╭─────╮ ╭─────╮
│活动B│ │活动C│ ← B和C并发执行
╰──┬──╯ ╰──┬──╯
⇨ ⇨
│ │
━━━━━━━━━━ ← 粗横线(汇合点)
╭─────┴─────╮
│ 活动 D │ ← B和C都完成后才继续
╰───────────╯
```
#### ⑦ 泳道Swimlane—— 纵向分区
> 标明每一步由**哪个对象/角色**负责。
```
┌──────────┬──────────┬──────────┐
│ 客户 │ 业务员 │ 系统 │
│ (泳道1) │ (泳道2) │ (泳道3) │
├──────────┼──────────┼──────────┤
│ │ │ │
│ ● │ │ │ ← 起点
│ ⇩ │ │ │
│ ╭───╮ │ │ │
│ │下单│ │ │ │ ← 客户下单
│ ╰─┬─╯ │ │ │
│ │ │ │ │
│ ⇨ │ │ │
│ ╭───╮ │ │
│ │接单│ │ │ ← 业务员接单
│ ╰─┬─╯ │ │
│ │ │ │
│ ⇨ │ │
│ ╭───╮ │
│ │处理│ │ ← 系统处理
│ ╰─┬─╯ │
│ │ │
└──────────┴──────────┴──────────┘
⊙ ← 终点
```
#### ⑧ 对象流Object Flow—— 虚线 + 箭头
> 表示活动之间**传递的对象**(数据)。
```
╭───────────╮ ┌──────────┐
│ 提交订单 │ ── ─ ─▶│ 订单 │ ← 虚线 + 箭头
╰───────────╯ └──────────┘
⇨ (对象流也指向下一个活动)
╭─────╮
│ 付款 │
╰─────╯
```
⚠️ **注意**:对象本身画成**矩形**(不是圆角矩形),虚线箭头表示"这个活动产生/使用了这个对象"。
#### ⑨ 完整活动图示例(不带泳道)
```
● 起点
╭─────────╮
│ 开始借书 │
╰────┬────╯
╭─────────╮
│ 扫描图书 │
╰────┬────╯
╭─────────╮
│ 扫描借书证│
╰────┬────╯
◇ 判断
[可借] ╲[不可借]
╭─────╮ ╭───────╮
│ 借出 │ │ 提示原因│
╰──┬──╯ ╰───┬───┯
⇩ ⇩ │ (汇合)
│ │ │
╰───◇ 汇合 ◇────╯
╭─────────╮
│ 结束 │
╰─────────╯
⊙ 终点
```
#### ⑩ 状态图元素的画法
> 状态图和活动图有些元素是**共用的**(起点/终点/转移箭头)。
**状态**:圆角矩形,**可带分区**(状态名 / 内部活动)
```
╭─────────────────────╮
│ 待机中 │ ← 第一行:状态名
├─────────────────────┤
│ entry / 初始化 │ ← 入口动作
│ do / 持续活动 │ ← 持续活动
│ exit / 清理 │ ← 出口动作
╰─────────────────────╯
```
**转移Transition**
```
╭──────────╮ 事件[条件]/动作 ╭──────────╮
│ 状态A │ ─────────────────▶ │ 状态B │
╰──────────╯ ╰──────────╯
格式:事件名[监护条件]/动作
例: 借出() / 可借数-1
```
**历史状态 H**:圆圈里写 H记录离开时的子状态
```
╭──────────╮
│ 复合状态 │
╰────┬─────╯
(H) ← 历史状态圆圈里写H
╭──────╮ ╱│╲
│ 子1 │◀─(H)─▶│ 子2 │ ← 回来时回到H记录的子状态
╰──────╯ ╰─────╯
```
🔑 **一句话记忆口诀**:实心圆是起点,牛眼是终点;圆角矩形是活动,菱形是分支;粗横线是分叉汇合,泳道是纵向分区,对象是普通矩形+虚线箭头。
---
### 🔑 状态 vs 活动(必考区别!)
| 对比 | 状态 | 活动 |
|------|------|------|
| **本质** | 对象所处的**境况** | 一段程序代码的**执行过程** |
| **持续时间** | 可以很长(等待状态) | 相对短暂(执行完就结束) |
| **关系** | 是活动执行后的**结果** | 是导致状态变化的**原因** |
| **关注对象** | 一个对象 | 可以涉及多个对象 |
| **UML图** | 状态图 | 活动图 |
💬 **比喻**:做菜的过程(洗菜→切菜→炒菜→装盘)是**活动**;菜做完了变成"已做好"是**状态**。
### 活动图的两种用途
1. **对业务流程建模**(不带泳道)—— 用于需求分析,描述用例的工作流程
2. **对系统操作建模**(带泳道)—— 用于系统设计,把步骤落实到具体对象
---
## ✍️ 边学边练(二)
**题目**:画出"借书"用例的带泳道活动图。
流程:图书管理员录入图书条码和借书证号 → 系统判断借书证能否借书 → 若不能,显示原因并结束 → 若能,生成借阅记录,修改可借本数。
**答案:**
**泳道划分**:图书管理员 | 系统
```
图书管理员泳道:
录入条码和借书证号 →
系统泳道:
判断能否借书 → [不能] → 显示原因 → 结束
→ [能] → 生成借阅记录 → 修改可借本数 → 结束
```
⚠️ 关键:分叉用菱形,两个分支最终汇合到结束。
---
## 💡 四、状态/活动与用例/方法的关系
### 状态与方法、用例的联系
- 一个方法的执行 → 属性值改变 → 对象进入新**状态**
- 对象处于不同状态 → 影响后续哪些**用例**可以执行
- 一个对象完整的状态图 = 多个用例的顺序图**融合**
### 活动与方法、用例的联系
- 一个**活动** = 一个方法中的部分(或全部)语句执行
- 一个方法可能需要多个活动来完成
- 一个**用例** = 若干个活动,通常一个用例对应一个活动图
---
## ✍️ 边学边练(三)
**题目**:借书证的状态图中有"可借书"和"不可借书"状态。问:
1. "借书"操作对应什么事件类型?
2. 从"不可借书"转回"可借书"需要什么事件?
3. "借书证"的状态图与哪些用例有关?
**答案:**
1. **调用事件**——"借书"本质上是对借书证对象调用借书方法
2. **还书事件**——读者还书后借书证的可借本数减1重新变为可借
3. 与"借书""还书""挂失借书证"等用例有关。这些用例的顺序图融合起来,就构成了借书证的完整状态图
---
## 📝 章末自测
**1. 填空题**
- 状态图描述的是( ____ )个对象的状态变化
- 四种事件类型是:调用事件、( ____ )、( _____ )、时间事件
- 活动图中的菱形表示( ____ ),粗横线表示( ___
**2. 判断题**
- ( ) 状态图和活动图都可以描述多个对象的交互
- ( ) 信号事件比调用事件更易于扩展
- ( ) 一个活动可能跨越多个泳道
- ( ) 带泳道的活动图用在系统设计阶段
**3. 简答题**
- 简述状态和活动的区别。
- 什么情况下应该用状态图,什么情况下应该用活动图?
**答案:**
**填空题**:一(单个);信号事件、变化事件;分支、分叉/汇合
**判断题**
- ❌ 状态图只描述一个对象
- ✅ 信号类可继承扩展
- ❌ 每个活动只属于一个泳道
- ✅ 带泳道用于设计阶段
**简答题**
- 状态是对象的境况(活动执行后的结果),可以持续很长时间;活动是代码的执行过程,相对短暂。状态变化由活动引起。
- 状态图:描述一个对象生命周期内的状态变迁(如订单状态、借书证状态)。活动图:描述一个业务流程或算法步骤(如取款流程、登录验证流程)。
---
> 🔗 上一篇:[第5章 顺序图与协作图](第05章-顺序图与协作图.md) | 下一篇:[第7章 组件图与部署图](第07章-组件图与部署图.md)

View File

@@ -0,0 +1,426 @@
# 第7章 组件图与部署图
> **考试重要度**:★★★
> **核心内容**:组件的概念与类型、组件与类的关系、正向工程与逆向工程、部署图与结点
---
## 📢 从盖房子理解物理模型
💬 前面学的用例图、类图、顺序图等是**逻辑模型**——描述"软件能干什么"和"软件怎么组织"。
组件图和部署图是**物理模型**——描述"软件代码文件怎么组织"和"软件部署在哪台机器上"。
```
逻辑模型:用例图 + 类图 + 顺序图 + 协作图 + 活动图 + 状态图
物理模型:包图 + 组件图 + 部署图
```
💬 **比喻**:逻辑模型是"建筑设计图"(几室几厅、什么风格),物理模型是"施工方案"(每间房用什么材料、电线怎么走)。
---
## 💡 一、组件的概念
> **定义**:组件 = 系统中可替换的物理部件,是一个实现性文件。
💬 **大白话**:组件就是"软插件"——像电脑的USB设备一样可以拔下来换一个。
### 组件的三种类型
| 类型 | 说明 | 举例 |
|------|------|------|
| **部署组件** | 运行时需要的组件 | DLL文件、JAR文件、数据库表、XML文件 |
| **工作产品组件** | 开发过程产生的组件 | 源代码文件(.java/.cpp)、数据文件 |
| **执行组件** | 运行后产生的组件 | EXE文件、动态网页、EJB |
---
## 💡 二、组件和类的关系
🔑 **这是本章最重要的理解!**
| 维度 | 类 | 组件 |
|------|-----|------|
| **性质** | 逻辑概念("虚" | 物理概念("实" |
| **存在形式** | 设计图上的符号 | 硬盘上的文件 |
| **包含关系** | 一个类只在一个组件中 | 一个组件可以包含多个类 |
| **例子** | `class BankAccount` | `BankAccount.java` 这个文件 |
💬 **简单说**:一个.java文件可以定义多个类这个.java文件就是**组件**里面的class定义就是**类**。
### 组件之间的关系
组件之间的关系 = 包含的类之间的关系的"投影"。
> 类A依赖于类B → 组件A依赖于组件B
---
## 💡 三、正向工程与逆向工程
| 工程方向 | 含义 | 过程 |
|----------|------|------|
| **正向工程** | 模型 → 代码 | 画好类图和组件图 → 工具自动生成代码框架 |
| **逆向工程** | 代码 → 模型 | 导入源代码 → 工具自动生成类图和组件图 |
💬 **正向工程**:先设计,再生成代码骨架。
💬 **逆向工程**:拿到别人写的代码,自动生成类图来理解结构。
---
## 💡 四、部署图
### 结点的概念
> **结点** = 运行时存在的、有计算能力的物理元素。
| 结点类型 | 说明 | 举例 |
|----------|------|------|
| **处理机结点** | 有计算能力的硬件 | PC机、服务器、打印机智能 |
| **设备结点** | 无计算能力的硬件 | 调制解调器、普通终端 |
### 部署图的作用
部署图显示:
1. 系统中有哪些**硬件结点**
2. 结点之间的**连接关系**(通信路径)
3. 每个结点上运行什么**组件**
💬 **一句话**:部署图 = "哪个软件组件跑在哪台机器上"。
---
## 📌 附录:组件图与部署图常用画图符号速查
> 这一节把组件图、部署图里所有的画图元素(组件、接口、结点、关系)用字符画列出来。
### 1. 组件Component—— 矩形 + 左侧两个小矩形
```
┌────┐
├────┤ ┌─────────────────┐
└────┘ │ <<component>> │ ← 字符画示意
│ OrderService │ ← 实际画法(两个小矩形贴在
└─────────────────┘ 组件图标的左上角)
```
更形象的字符画(标准画法的样子):
```
┌────────────────────────┐
│ ╔══════════════╗ │
╔═╧═╗║ OrderService ║ │ ← 左侧两个小方块
║ ║╚══════════════╝ │ 右侧大矩形是组件名
╚═══╝ │
└────────────────────────┘
```
简化字符画(更便于手写):
```
┌──┐
│ ├───── ┌────────────────┐
└──┘ │ OrderService │
└────────────────┘
```
⚠️ **命名方式**
- `OrderService.java` —— 包含扩展名的具体组件
- `<<component>>` + `OrderService` —— 用版型标识
### 2. 组件的两种画法
**带版型的标准画法**
```
┌──┐
│ ├───── ┌────────────────────┐
└──┘ │ <<component>> │
│ OrderService │
└────────────────────┘
```
**简化的文件/类表示法**(在组件图里很常见):
```
┌──┐
│ ├───── ┌────────────────────┐
└──┘ │ OrderService.java│ ← 写上扩展名
└────────────────────┘
```
### 3. 接口Interface—— 棒棒糖 / 插座
**棒棒糖表示法**(提供方在提供接口时用):
```
┌──────┐
客户端 │ 飞行 │ ← 圆圈 + 接口名
┌────┐ │ │
│ 鸟 │──●────┘ ↑ │ ← ● 是棒棒糖圆圈
└────┘ │ │
└───┘
```
**插座表示法**(需要方在实现接口时用):
```
┌────┐ ┌──────┐
│ 鸟 │ ─────────┤ 飞行 │
└────┘ ◀──── └──────┘
│ 半圆+连接线 │
│ (socket) │
```
简化字符画:
```
┌────────┐
│ 鸟 │ ●────── 飞行 (提供方lollipop)
└────────┘
┌────────┐
│ 飞机 │ ◀──半圆──── 飞行 (需要方socket)
└────────┘
```
### 4. 组件之间的关系
**依赖关系**(最常见 —— 一个组件调用另一个组件):
```
┌──┐ ┌──┐
│ ├──────┐ │ │
└──┘ │ └──┘
│ ┌────────────────┐
│ │ LoginService │
│ └────────────────┘
│ ┌────────────────┐
┌─────────┴─▶│ UserService │
│ ┌────────────────┐ │
└──│ LoginUI │ │
└────────────────┘ │
┌──┐ │
│ ├──┐ ┌────────────────┐ │
└──┘ └─▶│ DataService │◀───┘
└────────────────┘
(虚线箭头表示依赖)
```
简化画法(虚线箭头):
```
┌──────────────┐
│ OrderUI │
│ OrderCtrl │ ╌ ─ ─ ─ ─ ─▶ ┌──────────────┐
└──────────────┘ (依赖) │ OrderService│
└──────────────┘
```
**实现关系**(组件实现接口):
```
┌──────────────┐ ●──── 支付接口
│ 支付组件 │ ──────────── /
└──────────────┘ 实现关系
```
### 5. 结点Node—— 立方体
> 部署图的核心元素。立方体代表一台**物理设备**。
**字符画表现**(立方体用三视图):
```
┌──────────────┐
╱│ ╱│
┌──────────────┐ │
│ │ │ │
│ │ Web │ │
│ │ Server │ │
│ └───────────│──┘
│╱ │╱
└──────────────┘
```
**简化字符画**(考试/笔记常用):
```
┌──────────────┐
│ ┌────────┐ │
│ │ Web │ │ ← 立方体的"上表面"(可选)
│ │ Server │ │
│ └────────┘ │
└──────────────┘
┌──────────┐
╱│ Web ╱│
│ Server
┌──────────┐ │
│ ┌────┐ │ │
│ │名称│ │ │
│ └────┘ │ │
└──────────┘ │
│ │
└────────┘
```
最简洁的字符画(最推荐使用):
```
╔═══════════════╗
║ <<device>> ║ ← 设备结点
║ WebServer ║
╚═══════════════╝
```
**处理机结点 vs 设备结点**(都用立方体,靠版型区分):
```
处理机结点 设备结点
╔═══════════════╗ ╔═══════════════╗
║ <<processor>> ║ ║ <<device>> ║
║ WebServer ║ ║ Modem ║
╚═══════════════╝ ╚═══════════════╝
(有CPU可计算) (没有计算能力)
```
### 6. 结点内运行的组件
> 在结点立方体里"装"上组件,组件画在结点内部。
```
╔═══════════════════════════╗
║ <<processor>> ║
║ WebServer ║
║ ║
║ ┌──┐ ║
║ │ ├──── ┌────────────┐ ║
║ └──┘ │<<component>>║ ║
║ │ WebApp.jar │ ║
║ └────────────┘ ║
║ ║
║ ┌──┐ ║
║ │ ├──── ┌────────────┐ ║
║ └──┘ │<<component>>║ ║
║ │ DBDriver │ ║
║ └────────────┘ ║
╚═══════════════════════════╝
```
简化版本:
```
╔═══════════════╗
║ WebServer ║
║ ║
║ ┌──┐ ║
║ │ ├─ WebApp ║ ← 组件在结点里
║ └──┘ ║
╚═══════════════╝
```
### 7. 结点之间的连接
> 部署图上的"线"表示物理通信路径。
```
╔═══════════╗ ╔═══════════╗
║ 客户端 ║ ║ 服务器 ║
║ (PC机) ║ ║ ║
╚═════╤═════╝ ╚═════╤═════╝
│ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ TCP/IP │
│ │
```
**多重连接**(同一对结点可能有多种连接):
```
╔═══════════╗ ╔═══════════╗
║ 客户端 ║ ━━━━━━━TCP/IP ━━━━━━━━━ ║ Web服务器 ║
║ ║ ━━━━━━━ HTTPS ━━━━━━━━━ ║ ║
╚═══════════╝ ╚═══════════╝
```
### 8. 完整部署图示例
```
TCP/IP
━━━━━━━━━━━━━━━━━━━━
╔══════════╗ ╔══════════════════╗
║<<device>>║ ║ <<processor>> ║
║ 客户机 ║ ║ Web服务器 ║
║ ║ ║ ║
║ ┌──┐ ║ ║ ┌──┐ ║
║ │ ├─◀━━╫━━━━━━调用━━━━━━━━╫──┤ ├─ WebApp.jar║
║ └──┘ ║ ║ └──┘ ║
║ 浏览器 ║ ║ ║
╚══════════╝ ╚══════════════════╝
│ JDBC
╔══════════════════╗
║ <<processor>> ║
║ 数据库服务器 ║
║ ║
║ ┌──┐ ║
║ │ ├─ MySQL.db ║
║ └──┘ ║
╚══════════════════╝
```
🔑 **一句话记忆口诀**:组件左上方两个小方块,接口是圆圈加棒棒糖;结点是立方体(靠版型区分处理机/设备),立方体里装组件,立方体之间是通信连接。
---
## ✍️ 边学边练
**题目**某Web系统包括以下内容请区分逻辑模型和物理模型。
① 用户类(User)、订单类(Order)
② User.java、Order.java放在src/entity目录下
③ 用户登录要用到LoginAction.java
④ 整个系统部署在一台Web服务器和一台数据库服务器上
⑤ 用户→登录界面→输入信息→验证→跳转主页
**答案:**
-**逻辑模型(类图)**—— 描述有哪些类
-**物理模型(包图+组件图)**—— 描述文件放哪个目录
-**物理模型(组件图)**—— 描述组件之间的依赖
-**物理模型(部署图)**—— 描述硬件部署
-**逻辑模型(顺序图/活动图)**—— 描述交互流程
---
## 📝 章末自测
**1. 填空题**
- 组件的三种类型是:( ___ ___ )、( ___ ___ )、( ___ ___
- 正向工程是指从( ___ ___ )生成( ___ ___
- 部署图中的结点分两种:( ___ ___ )和( ___ ___
**2. 判断题**
- ( ) 一个组件只能包含一个类
- ( ) 组件图描述的是系统的物理结构
- ( ) 部署图中的连接表示硬件之间的通信路径
- ( ) 类图是物理模型,组件图是逻辑模型
**3. 简答题**
- 简述组件和类的关系。
**答案:**
**填空题**:部署组件、工作产品组件、执行组件;模型、代码;处理机结点、设备结点
**判断题**:❌(可包含多个) ✅ ✅ ❌(反过来)
**简答题**
- 类是逻辑概念,组件是物理概念。一个组件(如.java文件可以包含一个或多个类。组件是为了"软插件"理念——将类打包成可替换的物理单元。类之间的关系决定了组件之间的关系。
---
> 🔗 上一篇:[第6章 状态图与活动图](第06章-状态图与活动图.md) | 下一篇:[第8章 包图](第08章-包图.md)

View File

@@ -0,0 +1,290 @@
# 第8章 包图
> **考试重要度**:★★
> **核心内容**:包的概念与可见性、包之间的依赖与泛化关系、四大设计原则
---
## 📢 从文件夹理解包图
💬 你电脑上肯定有文件夹(目录),用来把相关文件放在一起。
在UML中**包**就是"文件夹"——把关系密切的类、接口、组件等放在一起。
```
┌─────────────────┐
│ 包名 │
│ ┌───────────┐ │
│ │ + 公开类 │ │ ← 被import后外部可用
│ │ # 受保护 │ │ ← 只有子包可用
│ │ - 私有类 │ │ ← 只有包内部可用
│ └───────────┘ │
└─────────────────┘
```
---
## 💡 一、包的可见性
跟类的可见性一样,包中的元素也有三种可见性:
| 可见性 | 符号 | 含义 |
|--------|------|------|
| **公有** | `+` | 任何导入此包的包都可以用 |
| **受保护** | `#` | 只有子包可以用 |
| **私有** | `-` | 只有包内部可以用 |
---
## 💡 二、包之间的关系
### 1. 依赖关系
> 包A中的某个类依赖于包B中的某个类 → 包A依赖于包B。
⚠️ **注意**:包之间的依赖关系**没有传递性**A依赖BB依赖C不等于A依赖C。
### 2. 泛化关系
> 子包继承父包中可见性为public和protected的元素。
### 📌 包图各元素的画法速查
> 这一节把包图里所有的画图元素(包本身、依赖、泛化)用字符画列出来。
#### ① 包的两种画法
**标准文件夹画法**(最常用):
```
┌──────────────┐
│ UI层 │ ← 上方有"小标签"(像文件夹的舌头)
└──────────────┘
```
字符画表示(小标签在左上角):
```
┌────────────┐
│┌─┐ │
││ │ │
│└─┘─────────┤
│ UI层 │
│ │
│ ┌─────────┐ │
│ │ 登录页 │ │ ← 包内可以嵌套子包或类
│ └─────────┘ │
└─────────────┘
```
**简化画法**(只用矩形):
```
┌──────────────┐
│ UI层 │
│ ┌────────┐ │
│ │ 登录页 │ │
│ └────────┘ │
│ ┌────────┐ │
│ │ 主页面 │ │
│ └────────┘ │
└──────────────┘
```
#### ② 包的嵌套
```
┌──────────────────────┐
│ 电子商务系统 │
│ ┌──────────┐ │
│ │ 用户模块 │ │
│ │ ┌──────┐ │ │
│ │ │登录类│ │ │
│ │ └──────┘ │ │
│ │ ┌──────┐ │ │
│ │ │注册类│ │ │
│ │ └──────┘ │ │
│ └──────────┘ │
│ ┌──────────┐ │
│ │ 订单模块 │ │
│ └──────────┘ │
└──────────────────────┘
```
#### ③ 包的可见性符号
```
┌────────────────┐
│ ┌─┐ │
│ │+│ 公开类 │ ← + 公有:任何外部包都可用
│ └─┘───────────┤
│ ┌─┐ │
│ │#│ 受保护类 │ ← # 受保护:只有子包可用
│ └─┘───────────┤
│ ┌─┐ │
│ │-│ 私有类 │ ← - 私有:只有包内部可用
│ └─┘───────────┤
│ │
└────────────────┘
```
#### ④ 包之间的依赖关系 —— 虚线 + 开放箭头
> 一个包中的类**引用**另一个包中的类 → 包之间形成依赖。
```
┌──────────────┐ ┌──────────────┐
│ UI层 │ │ 业务层 │
│ │ │ │
│ ┌────────┐ │ │ ┌────────┐ │
│ │登录窗口 │ │ │ │登录服务 │ │
│ └────────┘ │ │ └────────┘ │
│ │ │ │
└──────────────┘ └──────────────┘
│ ▲
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘
虚线 + 开放箭头
依赖方向UI层 依赖 业务层)
```
⚠️ **依赖方向**:箭头从"使用者"指向"被使用者"(类似类图里的依赖)。
#### ⑤ 包之间的泛化关系 —— 实线 + 空心三角
> 子包继承父包的内容。子包继承父包中**public 和 protected** 的元素。
```
┌──────────────┐ ┌──────────────┐
│ 业务层 │ │ 通用层 │
│ (子包) │ ─ ─ ─ ─ ─ ─ ─ ▷ │ (父包) │
│ │ 空心三角 │ │
│ ┌────────┐ │ │ ┌────────┐ │
│ │订单处理 │ │ │ │日志工具 │ │
│ └────────┘ │ │ └────────┘ │
│ ┌────────┐ │ │ ┌────────┐ │
│ │支付处理 │ │ │ │通用工具 │ │
│ └────────┘ │ │ └────────┘ │
└──────────────┘ └──────────────┘
```
⚠️ **泛化方向**:空心三角**指向父包**(与类图泛化一致)。
#### ⑥ 完整包图示例
```
┌────────────────┐
│ 表现层 │
│ ┌────────┐ │
│ │登录页 │ │
│ └────────┘ │
│ ┌────────┐ │
│ │主窗体 │ │
│ └────────┘ │
└───────┬────────┘
│ 依赖
╌ ╌ ╌ ╌ ╌ ╌ ╌
┌────────────────┐ ▷ ┌────────────────┐
│ 业务层 │ ─ ─ ─ ─ ─ ─ ─ ─ ─│ 通用层 │
│ │ 泛化 │ │
│ ┌────────┐ │ │ ┌────────┐ │
│ │登录管理 │ │ │ │日志工具 │ │
│ └────────┘ │ │ └────────┘ │
│ ┌────────┐ │ │ ┌────────┐ │
│ │订单管理 │ │ │ │数据校验 │ │
│ └────────┘ │ │ └────────┘ │
└───────┬────────┘ └────────────────┘
│ 依赖
╌ ╌ ╌ ╌ ╌ ╌ ╌
┌────────────────┐
│ 数据层 │
│ ┌────────┐ │
│ │用户DAO │ │
│ └────────┘ │
│ ┌────────┐ │
│ │订单DAO │ │
│ └────────┘ │
└────────────────┘
```
🔑 **一句话记忆口诀**:包用文件夹画,标签是包名;包间依赖是虚线开放箭头(指向被依赖),包间泛化是实线空心三角(指向父包);包可以嵌套,元素分+/-可见性。
---
## 💡 三、包的四大设计原则
这些原则告诉你**怎么把类分到不同的包里**
### 1. 重用等价原则REP
> 把可以一起复用的类放在一个包中。包 = 可重用的单元。
💬 就像一个工具包——扳手和螺丝刀放在一起,因为它们总是一起用。
### 2. 共同闭包原则CCP
> 把需要同时修改的类放在一个包中。
💬 修改了类A就必须修改类B那它们应该在一个包里——改一个包就够了。
### 3. 共同重用原则CRP
> 不会一起用的类不要放在同一个包里。
💬 别把厨房用品和修车工具放一起——要用厨房用品的人不需要修车工具。
### 4. 非循环依赖原则ADP
> 包之间的依赖关系**不能形成环**。
💬 A→B→C→A 这样的循环依赖会严重妨碍复用。破解方法:提取共同接口或拆分包。
### 🔑 核心目标:高内聚、低耦合
| 原则 | 作用 |
|------|------|
| **高内聚** | 包内的类关系紧密REP + CCP |
| **低耦合** | 包之间的依赖尽量少CRP + ADP |
---
## ✍️ 边学边练
**题目**:判断以下做法是否合理。
1. 把订单处理类和用户登录类放在同一个包
2. A包依赖B包B包依赖C包C包依赖A包
3. 把所有工具类放在一个util包中让其他包依赖它
4. 把用户界面类、数据库访问类、业务逻辑类放在同一个包
**答案:**
1. ❌ 不合理 — 违反CRP不会一起使用的类不要放一起。订单处理的人不需要登录功能。
2. ❌ 不合理 — 违反ADP循环依赖
3. ✅ 合理 — 符合REP工具类作为可重用单元
4. ❌ 不合理 — 违反CCP和CRP。不同层次的类界面/数据/逻辑)修改原因不同,应该分开。
⚠️ **实用建议**通常按层次分包UI层、业务层、数据层而不是按功能分包。
---
## 📝 章末自测
**1. 填空题**
- 包的四大设计原则缩写是:( ___ ___ )、( ___ ___ )、( ___ ___ )、( ___ ___
- ADP原则要求包之间的依赖不能形成 ___ ___
- 包中元素的三种可见性是:公有( ___ ___ )、受保护( ___ ___ )、私有( ___ ___ )
**2. 简答题**
- 简述REP和CRP之间的矛盾是什么
- 包图和组件图的关系是什么?
**答案:**
**填空题**REP、CCP、CRP、ADP循环+、#、-
**简答题**
- REP说要把可一起复用的类放在一个包这可能导致一个包很大包含所有可能用到的类CRP说不会一起用的类要分开这可能导致很多小包。两者需要权衡。
- 包存放组件,组件包含类。包相当于文件夹,组件相当于文件。部署时:类→组件→包→结点。
---
> 🔗 上一篇:[第7章 组件图与部署图](第07章-组件图与部署图.md) | 下一篇:[第9章 数据建模](第09章-数据建模.md)

View File

@@ -0,0 +1,141 @@
# 第9章 数据建模
> **考试重要度**:★★★★
> **核心内容**:对象模型→数据模型的转换规则、多重性映射、泛化关系映射、三大范式
---
## 📢 从类图到数据库表
💬 前面用类图设计好了系统结构,但数据最终要存到数据库里。**数据建模**就是回答:怎么把"类"变成"数据库表"
---
## 💡 一、数据库设计的三个阶段
| 阶段 | 任务 | 产物 |
|------|------|------|
| **概念设计** | 把用户需求统一到一个逻辑结构中 | E-R图或UML类图 |
| **逻辑设计** | 转换为具体DBMS支持的数据模型 | 关系模式(表结构) |
| **物理设计** | 选择存储方式、索引策略等 | 在特定数据库上实现 |
💬 UML类图可以替代E-R图——类图不仅能描述数据还能描述行为触发器和存储过程
### 关键概念速查
| 概念 | 说明 |
|------|------|
| **主键** | 唯一标识一条记录的字段 |
| **外键** | 引用另一个表主键的字段 |
| **模式** | 所有表及表间关系的集合 |
| **索引** | 提高查询速度的数据结构 |
| **触发器** | 满足条件时自动执行的操作 |
| **存储过程** | 预编译的SQL语句集合 |
---
## 💡 二、对象模型 → 数据模型转换规则
### 基本转换规则
```
类 → 表
属性 → 字段(列)
操作 → 触发器/存储过程
类间关系 → 表间关系(或单独的表)
```
### 多重性在数据模型中的映射(重点!)
| 多重性 | 映射方法 |
|--------|----------|
| **1 对 0..\*** | 在多的一端加外键(指向一的一端的主键) |
| **0..1 对 1** | 在0..1一端加外键指向1的一端的主键 |
| **0..\* 对 0..\*** | 新建一个关联表,两端主键作为外键 |
> 例:客户(Customer) 1 —— 0..* 订单(Order)
>
> → Order表加外键 `customer_id` 指向 Customer表的主键。
> 例:学生(Student) * —— * 课程(Course)
>
> → 新建选课表(Enrollment),包含 `student_id` 和 `course_id` 两个外键。
### 泛化关系在数据模型中的映射(三种方案)
| 方案 | 做法 | 优点 | 缺点 |
|------|------|------|------|
| **方案一** | 父类和每个子类各建一个表 | 结构清晰 | 表多查询要JOIN |
| **方案二** | 不建父类表,父类属性放在每个子类表中 | 查询快 | 数据冗余 |
| **方案三** | 不建子类表,所有子类属性放在父类表中 | 表少 | 字段很多,有空值 |
💬 **方案一像"分家"**——各过各的,但联系起来需要花时间。
💬 **方案二像"合住但分灶"**——各自独立但有些东西重复了。
💬 **方案三像"大家庭"**——都在一个屋檐下,但人多事杂。
---
## 💡 三、三大数据库范式
| 范式 | 要求 | 解决的问题 |
|------|------|------------|
| **1NF** | 每个字段值都是**不可再分**的原子值 | 消除重复列 |
| **2NF** | 满足1NF + 非主键字段**完全依赖**主键 | 消除部分依赖 |
| **3NF** | 满足2NF + 非主键字段**不传递依赖**主键 | 消除传递依赖 |
💬 **1NF**:别在一个格子里塞多个值。
💬 **2NF**:每个字段只跟主键有关,别跟主键的一部分有关。
💬 **3NF**:非主键字段之间不要相互依赖。
---
## ✍️ 边学边练
**题目**以下表是否符合3NF如果不符合说明原因并修正。
```
订单表(Order)
订单ID (主键)
客户ID
客户姓名
客户电话
商品ID
商品名称
数量
下单日期
```
**答案:**
不符合3NF。存在传递依赖
- 客户姓名、客户电话 → 依赖客户ID不是直接依赖订单ID
- 商品名称 → 依赖商品ID不是直接依赖订单ID
**修正方案**(拆分成三个表):
- 订单表订单ID、客户ID、商品ID、数量、下单日期
- 客户表客户ID、客户姓名、客户电话
- 商品表商品ID、商品名称
这样每个非主键字段都直接依赖于所在表的主键满足3NF。
---
## 📝 章末自测
**1. 填空题**
- 1对多关联的映射方法是 ___ ___ )的一端加外键指向( ___ ___ )的一端
- 多对多关联的映射方法是:新建一个( ___ ___ ),两边的主键作为外键
- 3NF要求非主键字段之间没有 ___ ___ )依赖
**2. 简答题**
- 简述泛化关系映射的三种方案及其适用场景。
- 类图中的操作在数据模型中对应什么?
**答案:**
**填空题**:多、一;关联表;传递
**简答题**
- 方案一(每个类一个表):适合查询灵活、结构变化少的系统。方案二(父子属性合并到子表):适合子类差异大、按子类查询多的场景。方案三(所有属性合并到父表):适合子类差异小、字段不多的场景。
- 类图中的操作对应数据库中的**触发器和存储过程**。触发器是满足条件自动执行的代码存储过程是预编译的SQL程序。
---
> 🔗 上一篇:[第8章 包图](第08章-包图.md) | 下一篇:[第11章 RUP统一过程](第11章-RUP统一过程.md)

View File

@@ -0,0 +1,164 @@
# 第11章 Rational统一过程RUP
> **考试重要度**:★★★
> **核心内容**RUP的三大特点、四个阶段、九个核心工作流、六大最佳实践
---
## 📢 软件开发不只是写代码
💬 开发软件就像盖一座大楼——你不能上来就搬砖,得先画图纸、打地基、搭框架、装修……
**RUP** 就是一套完整的"盖楼流程指南",告诉你:什么人、在什么时候、做什么事、怎么做。
---
## 💡 一、RUP是什么
> **RUP (Rational Unified Process)** = 一套基于UML的软件开发过程框架。
🔑 **核心公式**RUP = **用例驱动** + **以体系结构为中心** + **迭代和增量开发**
### 三大特点
| 特点 | 含义 |
|------|------|
| **用例驱动** | 从用例出发,贯穿需求→设计→实现→测试全过程 |
| **以体系结构为中心** | 先搭建系统骨架,再逐步填充细节 |
| **迭代和增量开发** | 不是一口气做完,而是一轮一轮地完善 |
---
## 💡 二、RUP的二维结构
```
┌─────────────────────────────────────┐
纵轴 │ 工作流 │
(做 │ 业务建模 需求 分析设计 实现 测试 部署 │
什么) │ 配置管理 项目管理 环境 │
├─────────────────────────────────────┤
横轴 │ 初始 → 细化 → 构造 → 移交 │
(什么 │ ↑ ↑ ↑ ↑ │
时候) │ 里程碑 里程碑 里程碑 里程碑 │
└─────────────────────────────────────┘
```
---
## 💡 三、四个阶段(横轴)
| 阶段 | 核心任务 | 里程碑 |
|------|----------|--------|
| **初始 (Inception)** | 定义项目范围,评估可行性 | 生命周期目标里程碑 |
| **细化 (Elaboration)** | 设计体系结构,制定计划 | 生命周期体系结构里程碑 |
| **构造 (Construction)** | 大规模开发,完成所有功能 | 初始操作能力里程碑 |
| **移交 (Transition)** | 交付用户,培训,部署 | 产品发布里程碑 |
💬 **比喻**:初始=立项审批,细化=画施工图,构造=主体施工,移交=交房验收。
---
## 💡 四、九个核心工作流(纵轴)
### 六个过程工作流
| 工作流 | 做什么 | 主要产物 |
|--------|--------|----------|
| **业务建模** | 理解业务现状 | 业务用例模型、业务对象模型 |
| **需求** | 定义系统功能 | 用例模型、SRS |
| **分析与设计** | 设计系统结构 | 分析模型、设计模型、数据模型 |
| **实现** | 编写代码 | 源代码、可执行系统 |
| **测试** | 验证系统质量 | 测试计划、测试报告 |
| **部署** | 交付使用 | 安装包、用户手册、培训资料 |
### 三个支持工作流
| 工作流 | 做什么 |
|--------|--------|
| **配置与变更管理** | 控制制品版本和变更 |
| **项目管理** | 计划、分配、监控项目 |
| **环境** | 提供开发工具和过程支持 |
---
## 💡 五、4W概念
RUP回答了软件开发的四个基本问题
| 维度 | 问题 | RUP概念 |
|------|------|---------|
| **Who** | 谁来做? | 角色Role |
| **How** | 怎么做? | 活动Activity |
| **What** | 产出什么? | 制品Artifact |
| **When** | 什么时候做? | 工作流Workflow |
---
## 💡 六、六大最佳实践
🔑 **这是考试的常考点!**
| 最佳实践 | 含义 |
|----------|------|
| **① 迭代式开发** | 不是一次做完,而是多轮迭代,每轮都有一个可运行版本 |
| **② 管理需求** | 用用例来组织和管理需求,控制变更 |
| **③ 使用基于构件的体系结构** | 把系统设计成可替换的构件 |
| **④ 可视化软件建模** | 用UML图来描述系统结构和行为 |
| **⑤ 验证软件质量** | 把质量评估嵌入整个过程,不是事后检查 |
| **⑥ 控制软件变更** | 通过配置管理跟踪和控制每个修改 |
---
## 💡 七、迭代 vs 瀑布
| 维度 | 瀑布模型 | RUP迭代 |
|------|----------|---------|
| **节奏** | 需求→设计→编码→测试,一次性 | 多轮迭代,每轮都走完整流程 |
| **风险** | 到最后才发现问题 | 早期就能发现和解决风险 |
| **变更** | 不欢迎变更 | 每轮迭代可以调整方向 |
| **产出** | 最后才有可运行版本 | 每轮都有可运行版本 |
---
## ✍️ 边学边练
**题目**判断以下描述对应RUP的哪个阶段或工作流。
1. 项目经理制定本次迭代的计划
2. 测试人员编写测试用例并执行
3. 确定系统的技术架构是B/S还是C/S
4. 系统上线,培训用户使用
5. 绘制用例图,确定系统功能范围
**答案:**
1. **项目管理**(支持工作流)| 可在任何阶段
2. **测试**(过程工作流)| 主要在构造阶段
3. **细化阶段** — 设计体系结构
4. **移交阶段** — 交付给用户
5. **初始阶段****需求工作流** — 定义范围和功能
---
## 📝 章末自测
**1. 填空题**
- RUP的三大特点是 ___ ___ )、( ___ ___ )、( ___ ___
- RUP的四个阶段依次是 ___ ___ )、( ___ ___ )、( ___ ___ )、( ___ ___
- 九个核心工作流中6个是 ___ ___ 工作流3个是 ___ ___ )工作流
**2. 简答题**
- 简述RUP六大最佳实践。
- 迭代和增量开发相比瀑布模型有什么优势?
**答案:**
**填空题**
- 用例驱动、以体系结构为中心、迭代和增量开发
- 初始、细化、构造、移交
- 过程、支持
**简答题**
- ①迭代式开发 ②管理需求 ③使用基于构件的体系结构 ④可视化软件建模 ⑤验证软件质量 ⑥控制软件变更
- 迭代开发可以早期发现风险、更容易容纳需求变更、每轮都有可运行的版本(增强信心)、可以根据反馈及时调整方向。
---
> 🔗 上一篇:[第9章 数据建模](第09章-数据建模.md)