0 · 使用说明与考点地图
0.1 这份手册是什么
它把 SA4101C(Software Analysis and Design)Paper 1 可能考到的全部交付物拆成八块,每块按同一个结构写:考什么 → 语法 → 做法 → 例题(原题 + 分析 + 答案 + 图)→ 模拟题 → 常见错误 → 自检。
题源只有两类:C25 Term 1 真题(2025 年 11 月 3 日)与 C25 官方样卷。模拟题是按同一题型池新编的,难度与真题对齐,答案都给了完整推演,不是“要点提示”。
0.2 60 分怎么分布(真题)
| Section | 小问 | 交付物 | 分值 | 本手册章节 |
|---|---|---|---|---|
| A(30) VoyageLink | 1a | DDPP 表 | 6 | §7 |
| 1b | 用例图 | 8 | §1 | |
| 1c | 两张活动图(含实体) | 8 | §2 | |
| 1d | 屏幕 + 隐喻 | 4 | §8 | |
| 1e | 测试用例 + 测试数据 | 4 | §9 | |
| B(30) Pioneer Nation | 2 | 时序图(分析模型) | 12 | §3 |
| 3 | 多态设计(类/时序图) | 6 | §5 | |
| 4a | 两条坏味道 + 措施(文字) | 6 | §6 | |
| 4b | 重构后类图 | 6 | §4 |
样卷的结构略有不同:Section A 只有用例图 / 活动图 / 仪表盘三问(10+8+4),另外 8 分是精化用例图;Section B 是时序图 10 + 类图 10 + 重构 10。两种结构都要准备,因为 C26 可能沿用任意一种。
0.3 八类交付物与产能
| 交付物 | 卷面动词 | 耗时 | 最容易丢的分 |
|---|---|---|---|
| 用例图 | Draw the complete use case diagram | 15 min | 漏外部系统 actor |
| 活动图(含实体) | Draw the activity diagrams … include entities | 12 min/张 | 没有对象节点与状态 |
| 时序图(分析模型) | Construct a sequence diagram for the analysis model | 20 min | 缺返回消息 |
| 类图 | Produce a class diagram | 15 min | 多重性缺失或标反 |
| 多态设计 | By leveraging polymorphism, design … | 12 min | 客户端依赖具体类 |
| 坏味道 + 重构 | Identify … refactoring techniques | 8 min | 只会说“代码冗余”,叫不出名字 |
| DDPP 表 | … using the Descriptive-Diagnostic-Predictive-Prescriptive table | 12 min | 四层写成一个意思 |
| 屏幕 + 隐喻 / 测试用例 | Draw the screens … demonstrate metaphors / design test cases | 10 + 8 min | 隐喻只是装饰、测试只写正常路径 |
0.4 图索引(共 20 张)
每张图都放在它对应的题目后面。下表可用来快速跳转。
| # | 图 | 对应的题 |
|---|---|---|
| 00 | VoyageLink 用例图 | 真题 1b(8 分) |
| 01 | Loving Care 用例图 | 样卷 1a(10 分) |
| 02 | Loving Care 精化用例图 | 样卷 1d(8 分) |
| 03 | 健身房用例图 | 热身 / 模拟题 |
| 14 | 医院挂号用例图 | 模拟题 1 |
| 04 | VoyageLink 两张活动图 | 真题 1c(8 分) |
| 05 | Loving Care 两张活动图 | 样卷 1b(8 分) |
| 06 | 健身房活动图 | 热身 |
| 15 | 报销审批活动图 | 模拟题 2 |
| 07 | Apply Certified Course 时序图 | 真题 Q2(12 分) |
| 08 | Analyze Media 时序图 | 样卷 2a(10 分) |
| 09 | 图书馆借书时序图 | 模拟题 3 |
| 16 | 酒店入住时序图 | 模拟题 4 |
| 10 | Ask Matilda 类图 | 真题 Q3(6 分) |
| 11 | Analyze Media 类图 | 样卷 2b(10 分) |
| 12 | TrainingProvider 重构类图 | 真题 Q4b(6 分) |
| 13 | Project 重构类图 | 样卷 Q3(10 分) |
| 17 | 电商订单类图 | 模拟题 5 |
| 18 | 上帝类拆分类图 | 模拟题 6 |
| 19 | 医院预约线框图 | 模拟题 7 |
| 20 | 图书仪表盘线框图 | 模拟题 8 |
1 · 用例图 Use Case Diagram
卷面位置:真题 1b(8)/样卷 1a(10)、1d(8)。预算 15 分钟/张。
1.1 元素的六个位置
| 元素 | 画法 | 一句话规则 |
|---|---|---|
| Actor(参与者) | 小人 + 名称 | 按岗位命名(Doctor、Receptionist),不写人名 |
| System boundary | 方框 + 标题 | 框里只放本系统的用例;框外是 actor |
| Use case | 椭圆 | 必须是动词短语(Book Appointment),不是名词(Appointment) |
| Association | 实线,无箭头 | actor 与用例之间一律无箭头 |
| «include» | 虚线 + 开口箭头 → 被包含者 | 语义:必然执行的公共步骤 |
| «extend» | 虚线 + 开口箭头 → 基用例 | 语义:条件成立才执行的附加行为 |
| Generalization | 实线 + 空心三角 → 父 | actor 泛化(Staff ← Doctor)与用例泛化都算 |
| External system actor | 小人 + «system» | 凡是“另一个系统/平台/门户/引擎”,都是 actor |
1.2 include 还是 extend:一个判断句
把两句话说出来,哪句通就选哪个:
“做 A 必然要做 B。”
→
Book Shipment --«include»--> Search Availability订舱一定要先查舱位;箭头指向 B(被包含者)。
“做 A 有时要做 C(条件成立才做)。”
→
Cancel Order --«extend»--> Place Order取消是下单后的可选分支;箭头指向 A(基用例)。
1.3 四步法
- 扫人:把叙述里每个“谁做什么”写成
岗位(人名)。姓名只用来定位岗位。 - 扫系统:出现“平台/门户/引擎/网关/系统/数据源”的,全部列为 actor 并标 «system»。这一步决定能不能上 7 分。
- 抽用例:一个业务动作一个椭圆,用动词短语;不写“管理/处理/维护”这种糊词。
- 连关系:先画全部 association,再补 include/extend,最后检查泛化是否需要。
1.4 例题 1|真题 1b:VoyageLink(8 分)
- 题干把流程切成四段(pre-purchase / logistics / custom clearance / receiving),这就是覆盖度的评分线:每段至少要有 2–3 个用例。
- 三个叙述者对应三个岗位:Amy(采购与客户管理)、Danny(采购与物流计划)、Peter(物流与关务经理)。CEO Jonathan 只出现在“任命你”那段,不操作系统,不能画成 actor。
- 外部系统被点名四次:航运公司在线订舱平台、海关门户、仓库库存系统,以及天气/地缘风险数据源(1a 的 DDPP 数据来源)。
- include 有两处(订舱依赖查舱位;报关依赖备单证),extend 有一处(异常才改航),这三条正好覆盖 8 分里的“关系”分。
| 类别 | 内容 |
|---|---|
| Actor(人,3) | Amy / Danny / Peter |
| Actor(系统,4) | Shipping Lines Platforms、Customs Portal、Warehouse Inventory System、Weather & Risk Feed(均标 «system») |
| Use case(12) | Maintain Supplier & Buyer Records、Negotiate & Sign Contract、Notify Buyer & Arrange Pickup、Search Ship Space Availability、Book Shipment、Plan & Optimize Route、Track Shipment、Handle Disruption & Reroute、Share Container Space、Prepare Documentation、Submit Customs Clearance、Receive Goods into Inventory |
| 关系 | Book Shipment ⊃ Search Ship Space Availability(include) Submit Customs Clearance ⊃ Prepare Documentation(include) Handle Disruption & Reroute ⇢ Track Shipment(extend) |
① “Share Container Space” 看起来像内部功能,但案例明说“gain revenue through fees”,是业务价值点,漏了少一个用例;
② “Weather & Risk Feed” 不画,1a 的预测性分析和 1c 的活动图都会失去依据;
③ 别给 actor 与用例之间加箭头。
1.5 例题 2|样卷 1a:Loving Care(10 分)
- 关键词是 all stakeholders。案例里出现六个人(Jane、Tom、Jerry、John、Patient、Caregiver)和两个外部系统(卫生部、药房),漏一个就丢 1–2 分。
- Jane 的两个痛点是“先核实身份、再查团队可用”,这两件事必然发生在预约里 → 两条 include。
- John 的两项需求分别产生一个外部 actor(补贴申请 → 卫生部系统)和两个新 actor(自助入口 → 患者与看护者)。
- “开处方 → 看护者就近买药” 是条件行为(需要用药才发生)→ extend,且它带来一个外部系统 actor(Pharmacy)。
| 类别 | 内容 |
|---|---|
| 人(6) | Jane(Coordinator)、Tom(Doctor)、Jerry(Physiotherapist)、John(Supervisor)、Patient、Caregiver |
| 系统(2) | Government Health Ministry System、Pharmacy |
| 用例(14) | Register / Update Patient Profile · Verify Patient Identity · Issue Queue Number · Collect Fees · Check Care Team Availability · Book Appointment · Assign Fixed Care Team · Conduct Online Consultation · Conduct Home Visit · Prescribe Medication · Upload Exercise Video · Update Treatment Record · Share Treatment Update with Caregiver · View Appointment / Treatment Status · Submit Subsidy Claim |
| 关系 | Book Appointment ⊃ Verify Patient Identity Book Appointment ⊃ Check Care Team Availability Prescribe Medication ⇢ Conduct Online Consultation(条件:需用药) |
1.6 例题 3|样卷 1d:精化(8 分)
- 题目点名四样东西,缺一扣分:include、extend、用例泛化、actor 泛化。
- actor 泛化要有案例依据:Jane、Tom、Jerry 都是机构人员 → 提炼出父 actor
Loving Care Staff,通用用例(查看病人记录)连父。 - 用例泛化要有“子类是一种父类”的语义:预约可以细分为门诊预约与上门预约。
- 三种线的画法不能混:include/extend 虚线开口箭头;泛化实线空心三角。
| 类型 | 内容 | 符号 |
|---|---|---|
| «include» | Book Appointment ⊃ Check Care Team Availability | 虚线 + 开口箭头(指向被包含者) |
| «extend» | Prescribe Medication ⇢ Conduct Online Consultation | 虚线 + 开口箭头(指向基用例) |
| Actor 泛化 | Loving Care Staff ← Jane / Tom / Jerry | 实线 + 空心三角(指向父) |
| 用例泛化 | Book Appointment ← Book Clinic Appointment / Book Home Visit Appointment | 实线 + 空心三角(指向父) |
1.7 模拟题 1|医院挂号系统(8 分)
- 人:Patient、Doctor、Nurse 三个岗位。注意“挂号窗口职员”没有出现在叙述里,别自己加。
- 系统:Insurance System、SMS Gateway 都是 actor —— 短信网关很容易被误画成“系统内部的一个动作”。判断标准是:它在系统之外、由别人提供。
- 关系:预约必须查号源(include);退号是预约之后的可选动作(extend);在线支付在无差额时才不需要走医保理赔 → Claim 用 include 挂在支付下。
- 覆盖度:患者的四个动作、医生的两个、护士的一个,共 8 个用例,全部要有 actor 连线。
| 类别 | 内容 |
|---|---|
| Actor(人) | Patient、Doctor、Nurse |
| Actor(系统) | Insurance System(«system»)、SMS Gateway(«system») |
| Use case | Book Appointment、Check Slot Availability、Cancel Appointment、Pay Online、Insurance Claim、View Roster、Issue Prescription、Triage Patient、View Report |
| 关系 | Book Appointment ⊃ Check Slot Availability(include) Cancel Appointment ⇢ Book Appointment(extend) Pay Online ⊃ Insurance Claim(include) |
SMS Gateway 负责“提醒”,它连到 Book Appointment 与 Cancel Appointment 都可以;只要把系统 actor 画出来,连线连到哪个用例不会扣分。
1.8 模拟题 2|健身房会员系统(5 分钟热身)
1.9 模拟题 3|纯文字题:谁不是 actor
| 候选 | 是否 actor | 理由 |
|---|---|---|
| Student | 是 | 直接操作系统完成选课 |
| Registrar | 是 | 审批动作在系统内完成 |
| Finance Office | 是(«system») | 外部系统,接收数据 |
| Timetable engine | 是(«system») | 外部服务,分配教室 |
| Vice-Dean | 不是(或仅弱相关) | 他只设定一次业务规则,不通过系统完成任何用例;规则应在需求/约束里描述。若要建模,也应作为 business rule 而非 actor |
判分点:前四个列出 4 分,指出 Vice-Dean 并给出“不参与用例”的理由 2 分。
1.10 常见错误
| 错误 | 后果 | 修正 |
|---|---|---|
| 漏掉外部系统 actor | 通常丢 2–3 分 | 读题时专门用一支笔划“平台/门户/系统/网关” |
| include 与 extend 方向反 | 丢 1 分,且暴露概念不清 | include 指被包含者;extend 指基用例 |
| 画了 Login / Generate Report | 两套卷子都明确排除,可能倒扣 | 题干有 exclude 语句时,先划掉这两类 |
| 用例名是名词(Appointment) | “动词短语”那一分没了 | 统一用动宾:Book Appointment |
| actor 与用例之间画箭头 | 符号分 | 实线无箭头 |
| 把 CEO / 客户 / 上级主管画成 actor | 多余元素占版面,可能被判“未按要求” | 只有真正操作系统的人才画 |
1.11 自检清单
- 人按岗位、系统标 «system»,两类都齐。
- 有系统边界和名字;用例 8–14 个,覆盖叙述每一段。
- include 至少 1 条、extend 至少 1 条(若题目未要求可少,但有了更稳)。
- 用例名与案例用词一致;没有 login / 报表。
- 图能不看文字就读懂:actor 在两侧,用例按业务流分区排列。
2 · 活动图(含实体)Activity Diagram with Entities
卷面位置:真题 1c(8 分,两张)/样卷 1b(8 分,两张)。预算 12 分钟/张,两张共 25 分钟。
2.1 为什么叫“含实体”
课程把活动图分成两步:第一步画纯业务流程(泳道里只有人),第二步要求把实体状态变化画进去。卷面原话是 You are required to include entities in these activity diagrams. 判分表里必然有一条“有没有对象节点”。没有它,这张图最多拿一半分。
2.2 八个元素
| 元素 | 画法 | 规则 |
|---|---|---|
| Swimlane / Partition | 竖三条:Actor | System | Entity | 一张图固定三列,不要按人名分列 |
| Initial node | 实心圆 | 一张图一个 |
| Action | 圆角矩形 | 动词开头;一条泳道只放一个动作 |
| Decision node | 菱形 | 每条出边写 guard:[yes] / [no] |
| Merge node | 菱形 | 分支收回用;不要拉成蜘蛛网 |
| Object node | 矩形 + Entity [state] | 实体名 + 方括号状态,放 Entity 列 |
| Dashed arrow | 动作 → 对象节点 | 表示“这个动作改变了状态” |
| Activity final | 牛眼 | 别忘了,白丢 1 分 |
Booking [reserved]、Payment [paid]。状态必须是名词/形容词,不是动作(写 Booking [reserving] 会被判不规范)。2.3 四步法
- 选用例:1c 规定“支撑 1a 的数据驱动设计”,所以 1a 写预测,这里就画预测/应对;样卷给的是“任选两个业务关键用例”,要能一句话说清为什么关键。
- 摘步骤:从案例里摘 6–8 步,超过 10 步就合并动作(每张只值 4 分)。
- 分泳道:人做的进第一列,系统处理的进第二列,只有状态变了才进第三列。
- 加判断与实体:至少一个
[yes]/[no],至少两个实体状态,最后补结束节点。
2.4 例题 1|真题 1c:VoyageLink 两张活动图(8 分)
- “选用例”本身就是 2 分。1a 的痛点是 Danny 无法预测中断,所以两张图要落在预测与应对:Monitor Shipment & Predict Delay、Handle Disruption & Reroute。
- 每张 4 分 → 6–8 个动作足够,画 20 步必然超时。
- 实体跟着动作走:算 ETA 时是
[in transit],超阈值时产生Alert [raised],改航后Booking [revised]。
| 步 | 泳道 | 动作 / 判断 | 实体状态 |
|---|---|---|---|
| 1 | System | Pull schedule, weather & risk data | — |
| 2 | System | Calculate ETA | Shipment [in transit] |
| 3 | System | ◆ Delay above threshold? | — |
| 4a | System | [no] Update status & keep monitoring(回 1) | Shipment [on schedule] |
| 4b | System | [yes] Raise delay alert | Alert [raised] |
| 5 | System | Notify Danny / Amy / Peter | Notification [sent] |
| 6 | — | 结束 | — |
图 B:Handle Disruption & Reroute
| 步 | 泳道 | 动作 / 判断 | 实体状态 |
|---|---|---|---|
| 1 | Actor(Danny) | Review delay alert | — |
| 2 | System | Query alternative routes | Route [proposed] |
| 3 | Actor(Danny) | ◆ Accept reroute? | — |
| 4a | Actor(Danny) | [no] Keep original plan | Shipment [delayed] |
| 5a | Actor(Amy) | Inform buyer of the new ETA | Notification [sent] |
| 4b | System | [yes] Re-book vessel & update ETA | Booking [revised] |
| 6 | Actor(Peter) | Update customs documents | CustomsDocument [updated] |
| 7 | — | 结束 | — |
实体清单:Shipment、Alert、Route、Booking、Notification、CustomsDocument。
2.5 例题 2|样卷 1b:Loving Care 两张活动图(8 分)
| 步 | 泳道 | 动作 / 判断 | 实体状态 |
|---|---|---|---|
| 1 | Actor | Request appointment (clinic / home visit) | — |
| 2 | System | Verify patient identity | Patient [verified] |
| 3 | System | Check team availability | MedicalTeam [checked] |
| 4 | System | ◆ Slot available? | — |
| 5a | System | [no] 回到第 3 步换时段(图中回路) | — |
| 5b | System | [yes] Create appointment | Appointment [confirmed] |
| 6 | System | Assign fixed care team | MedicalTeamAssignment [created] |
| 7 | System | Notify patient & team | Notification [sent] |
图 2:Update Treatment Record & Notify Caregiver
| 步 | 泳道 | 动作 / 判断 | 实体状态 |
|---|---|---|---|
| 1 | Actor(Tom/Jerry) | Record consultation / therapy outcome | — |
| 2 | System | Save treatment record | TreatmentRecord [updated] |
| 3 | System | ◆ Condition changed? | — |
| 4a | System | [no] Save only, no push | — |
| 4b | System | [yes] Draft status update | StatusUpdate [drafted] |
| 5 | System | Push to caregiver & team | Notification [sent] |
| 6 | Actor(Caregiver) | View and acknowledge | StatusUpdate [acknowledged] |
| 7 | System | Log acknowledgement time | Acknowledgement [logged] |
2.6 模拟题 1|报销审批(8 分)
ExpenseClaim [submitted] → ◆Amount > 500? → [no] Auto-approve → Trigger payment;[yes] Assign to manager → ◆Approved? → [yes] Trigger payment → Payment [paid] → Notify → Notification [sent];[no] Reject → ExpenseClaim [rejected] → 结束。2.7 模拟题 2|健身房预约(5 分钟)
SeatAllocation [reserved] → Booking [confirmed];没名额 → Booking [waitlisted] → Waitlist [queued];两支汇合后发送通知 → Notification [sent]。2.8 模拟题 3|只给 basic flow,自己补泳道
1. The employee selects “Apply Leave” and enters the dates and reason.
2. The system checks the employee’s remaining leave balance.
3. If the balance is insufficient, the system displays a warning and the use case ends.
4. If sufficient, the system creates a leave application with status pending.
5. The system routes the application to the employee’s supervisor.
6. The supervisor approves or rejects.
7. The system updates the status and notifies the employee.
8. The use case terminates.
Draw the corresponding activity diagram with entities. (8 marks)
| 步 | 泳道 | 动作 / 判断 | 实体状态 |
|---|---|---|---|
| 1 | Actor(Employee) | Enter dates and reason | — |
| 2 | System | Check leave balance | LeaveBalance [checked] |
| 3 | System | ◆ Balance sufficient? | — |
| 4a | System | [no] Display warning | — |
| 4b | System | [yes] Create leave application | LeaveApplication [pending] |
| 5 | System | Route to supervisor | Notification [sent] |
| 6 | Actor(Supervisor) | ◆ Approve? | — |
| 7a | System | [yes] Update status | LeaveApplication [approved] |
| 7b | System | [no] Update status | LeaveApplication [rejected] |
| 8 | System | Notify employee | Notification [sent] |
注意:第 3 步的 [no] 分支应直接到结束节点,不要汇入第 8 步——否则语义变成“余额不足也通知审批结果”。
2.9 常见错误
| 错误 | 后果 |
|---|---|
| 没有 Entity 泳道或没有对象节点 | 直接失去“含实体”那 2 分 |
| 把活动图画成流程图(无泳道) | 结构分全失 |
| 判断节点出边没有 guard | 每个判断扣 0.5 |
| 两个动作画在同一个框里(“校验并通知”) | 职责混淆,且违反“一条泳道一件事” |
| 实体状态写成动词进行时 | 规范分 |
| 漏掉结束节点 | 0.5–1 分 |
2.10 自检清单
- 三列泳道(Actor / System / Entity)齐全,有初始与结束节点。
- 6–8 个动作,每个动作只属于一条泳道。
- 至少一个判断,且每条出边都有
[yes]/[no]。 - 至少两个对象节点,且状态随流程变化。
- 虚线从“改变状态的那个动作”指向实体。
3 · 时序图(分析模型)Sequence Diagram for the Analysis Model
卷面位置:真题 Q2(12 分)/样卷 2a(10 分)。预算 20–25 分钟,是 Section B 单题最高分。
3.1 什么叫“分析模型”
| 类型 | 职责 | 命名 | 本题实例 |
|---|---|---|---|
| Boundary(边界/UI 类) | 与 actor 交互:显示数据、收集输入,不含业务规则 | :FormXxx | :FormApplyCourse |
| Control(控制类) | 协调一个用例的流程,调实体、把结果交给边界 | :XxxControl | :ApplyCourseControl |
| Entity(实体类) | 需要持久保存的业务信息 | 业务单数名 | :Course、:Credit、:ResidentProfile |
| Actor | 发起者 | :Role | :Resident |
| External system | 外部服务 | :System | :ProviderSystem、:PaymentGateway |
一个用例通常就是 1 个边界 + 1 个控制 + N 个实体。画成“一个动作一个控制类”是最常见的崩盘点。
3.2 一步三消息:怎么把文字展开
基本事件流里一句 “the system retrieves and displays X”,实际包含三个动作:
| # | 箭头 | 含义 |
|---|---|---|
| ① | Control → Entity | 去取数据(findXxx) |
| ② | Entity → Control | 返回消息(虚线 + 开口箭头) |
| ③ | Control → Boundary | 把数据交给界面显示(displayXxx) |
如果这一步是用户触发的,前面还要加一条 Boundary → Control 的触发消息,于是变成四条。
3.3 13 步为什么会长成 24 条
| 步 | 内容 | 消息数 |
|---|---|---|
| 1 | 点击选项 | 1 |
| 2 | 查询并显示机构/课程 | 4 |
| 3 | 选择课程 | 1 |
| 4 | 查询并显示班级/学费 | 4 |
| 5 | 选择班级 | 1 |
| 6 | 查询并显示学分详情 | 4 |
| 7 | 确认班级 + 学分数额 | 1 |
| 8 | 取居民档案(不显示) | 2 |
| 9 | 发送给培训机构系统 | 2 |
| 10 | 差额 → 支付网关(条件) | 2 + alt 框 |
| 11 | 扣减学分 | 1 |
| 12 | 显示成功 | 1 |
| 13 | 结束 | 0 |
| 合计 | 24 | |
3.4 条件分支:alt 与 opt
左上角五边形写
alt;每个 operand 第一行写 guard;两个 operand 之间画水平虚线。只有一个 operand,条件成立才执行。本题的“有差额才付”用 alt 更完整。
┌─ alt ───────────────────────────────┐
│ [shortfall > 0] │
│ Control → :PaymentGateway │
│ makePayment(shortfall) │
│ :PaymentGateway → Control │
│ paymentStatus (虚线返回) │
│ ─────────────────────────────────── │
│ [no shortfall] (跳过) │
└─────────────────────────────────────┘
3.5 例题 1|真题 Q2:Apply Certified Course(12 分)
1. This use case is initiated when the resident clicks the ‘Apply Certified Course’ option on the Main Screen.
2. The system retrieves and displays the list of certified training providers, as well as the list of courses provided by them.
3. The resident selects the course that he is interested to attend.
4. The system retrieves and displays the list of classes under the course, including the course fees.
5. The resident selects the classes he is interested to attend.
6. The system retrieves and displays the Skills Empowerment Credit details belonging to the resident (available and utilized credit).
7. The resident confirms the class he likes to attend with the amount of the available credit that he likes to utilize.
8. The system retrieves the resident profiles such as his identification number, contact number and address.
9. The system sends the resident’s profile and his available credit to the Certified Training Provider System of the class selected; which handles the class registration.
10. If there is any shortfall between the available credit and the course fees, the system will invoke the Payment Gateway for the resident to make the payment to the provider.
11. The system deducts the Skills Empowerment Credit accordingly. [Transfer of the credit to the provider is handled by another use case.]
12. The system displays a successful message.
13. Use Case Terminates.
You are required to analyse the above use case. Construct a sequence diagram for the analysis model by referring to the basic flow of events. (12 marks)
- 分析模型=边界/控制/实体三类对象。本题的实体从名词里来:课程与班级(Course)、学分(Credit)、居民档案(ResidentProfile);两个外部系统单独作生命线。
- 第 2、4、6 步都是“查询并显示”,各展开 4 条消息;第 8、9 步是“取数据/发外部”,各 2 条。
- 第 10 步是条件分支,用
alt [shortfall > 0]包住支付网关的两条消息。 - 第 11 步“扣减学分”只需要一条 Control → Credit 的消息(内部计算,不必返回给界面)。
| 步 | 消息 |
|---|---|
| 1 | :Resident → :FormApplyCourse applyCertifiedCourse() |
| 2 | Form → Control getProviderAndCourseList();Control → Course findAllCourses();Course → Control courseList(返回);Control → Form displayProvidersAndCourses() |
| 3–5 | selectCourse(courseId);getClasses(courseId) / findClasses() / classList / displayClassesAndFees();selectClass(classId) |
| 6 | getCreditDetails(residentId) / findCredit() / creditDetails / displayCredit() |
| 7–8 | confirm(classId, creditAmt);getProfile(residentId) / profile(返回) |
| 9 | Control → :ProviderSystem sendRegistration(profile, credit) / registrationStatus(返回) |
| 10 | alt [shortfall > 0]:Control → :PaymentGateway makePayment(amount) / paymentStatus(返回) |
| 11–13 | deductCredit(amount);displaySuccess();showConfirmation() |
3.6 例题 2|样卷 2a:Analyze Media(10 分)
<Basic flow of events> — Analyze Media
1. This use case is initiated when the admin actor selects this option.
2. This use case allows the admin to select the media files by the list of media, or by the artists.
3. The system retrieves the usage (frequency of play) of the selected media files.
4. The system sends the consolidated list of the selected media files with its artist and usages to the BI Engine.
5. Use Case terminates.
Produce a sequence diagram to model the object interactions for the Analyze Media Use Case. (10 marks)
- 只有 5 步,消息 10–12 条即可;实体只有
:Media,不要为了凑数造出三四个实体。 - 第 3 步展开成 getUsage → usageData → displayMediaWithUsage。
- 第 4 步的接收方是外部系统,发出去之后要有一条返回(acknowledgement),否则调用链断掉。
:Admin / :FormAnalyzeMedia / :AnalyzeMediaControl / :Media / :BIEngine;消息 12 条,最后两条是 displaySuccess 与 showConfirmation。3.7 模拟题 3|酒店入住(10 分)
:Guest / :FormCheckIn / :CheckInControl / :Reservation / :Room;消息 10 条:
1 checkIn(reservationId) → 2 verifyReservation(id) → 3 findReservation(id) → 4 reservationData(返回)→ 5 checkRoomAvailability() → 6 roomStatus(返回)→ 7 markCheckedIn() → 8 updateRoomStatus(occupied) → 9 displayKeyCard() → 10 showConfirmation()。3.8 模拟题 4|图书馆借书(5 分钟)
:Member / :FormLoanBook / :LoanControl / :Book / :Loan;12 条消息,两次返回(bookAvailable、loanId)。3.9 模拟题 5|只给一句用例描述
基本流:① 艺人选择 Upload Media;② 系统显示上传表单;③ 艺人选文件并填标题/类型;④ 系统校验格式与大小;⑤ 系统保存媒体,状态 pending;⑥ 系统创建待审任务并通知审核员;⑦ 显示成功。
| # | 消息 |
|---|---|
| 1–2 | Artist → Form uploadMedia();Form → Control showUploadForm() |
| 3–4 | Artist → Form selectFile(file, metadata);Form → Control validateAndSave(file) |
| 5–6 | Control → Media create(file, “pending”);Media → Control mediaId(返回) |
| 7–9 | Control → ReviewTask create(mediaId);Control → Form displaySuccess();Form → Artist showConfirmation() |
3.10 常见错误
| 错误 | 后果 |
|---|---|
| 消息全是实线,没有虚线返回 | 丢 2 分且逻辑不闭合 |
| 把数据库/DAO/SQL 画进来 | 题目明确“不需要建模数据库”,画了不加分 |
| actor 直接发消息给实体 | 跳过边界与控制,分析模型不成立 |
| 编号与 basic flow 对不上 | “消息对应”那 4 分受影响 |
| 条件分支不画 alt/opt | 丢 1–2 分(第 10 步那种明显分支) |
3.11 自检清单
- 1 个边界、1 个控制、N 个实体、若干外部系统,命名符合规范。
- 13 步(或题给步数)每一步都能在图上找到对应消息。
- 编号连续;至少 5 条虚线返回。
- 条件分支用 alt 框或至少标注 guard。
- 没有画数据库层。
4 · 类图与多重性 Class Diagram
卷面位置:样卷 2b(10 分,只画类与关系)/真题 Q4b(6 分,重构后类图)。预算 15 分钟。
4.1 类框的三段与可见性
┌─────────────────────┐
│ ClassName │ ← 类名(抽象类可写 «abstract» 或斜体)
├─────────────────────┤
│ - id : String │ ← 属性:可见性 名称 : 类型
│ # rate : double │
├─────────────────────┤
│ + getId() : String │ ← 操作:可见性 名称(参数) : 返回
└─────────────────────┘
| 符号 | 可见性 |
|---|---|
+ | public |
- | private |
# | protected |
~ | package |
属性一律用 -(private)最稳;原代码里的 protected 是坏味道的一部分,重构时顺手改掉。
4.2 六种关系与画法
| 关系 | 符号 | 语义 | 典型用法 |
|---|---|---|---|
| Association 关联 | 实线,两端标多重性 | 两者有结构关系 | Customer 1 — 0..* Order |
| Aggregation 聚合 | 空心菱形在整体端 | 整体与部分可独立存在 | Customer ◇— Address |
| Composition 组合 | 实心菱形在整体端 | 部分随整体消亡 | Order ◆— OrderLine |
| Generalization 泛化 | 实线 + 空心三角→父 | is-a | Payment ▷ CreditCardPayment |
| Realization 实现 | 虚线 + 空心三角→接口 | 实现接口 | StripeGateway ⇢ IPaymentGateway |
| Dependency 依赖 | 虚线 + 开口箭头 | 临时使用(调用/参数) | Form ⇢ Control |
4.3 多重性怎么读
数字写在线两端,它修饰自己这一端的类:站在一端,读另一端的数字。
Customer 1 ──────── 0..* Order
① ②
① 一个 Customer 对应多少 Order?答:0 到多个
② 一个 Order 对应多少 Customer?答:1 个
| 写法 | 含义 | 例子 |
|---|---|---|
1 | 恰好一个 | 订单只有一个下单人 |
0..1 | 零或一个(可选) | 一笔订单最多一张优惠券 |
* | 零或多个(= 0..*) | 商品可被 0 个或多个订单行引用 |
1..* | 至少一个 | 订单至少有一个订单行 |
2..4 | 区间 | 一个团配 2–4 名导游 |
*(* 允许 0);以及把两个数字都写在同一端。4.4 例题 1|样卷 2b:Analyze Media 类图(10 分)
| 类 | 构造型 | 关系 |
|---|---|---|
| FormAnalyzeMedia | «boundary» | ⇢ AnalyzeMediaControl(«use») |
| AnalyzeMediaControl | «control» | — Media(1 — 0..*);⇢ BIEngine |
| Media | «entity» | — MediaUsage(1 — 0..*) |
| MediaUsage | «entity» | 记录播放频次 |
| BIEngine | «boundary» / external | 接收合并清单 |
4.5 例题 2|真题 Q4b:TrainingProvider 重构后类图(6 分)
public class BlacklistedTrainingProvider extends TrainingProvider { private String blacklistedReason; private Date blacklistedDate; }b) Refactor the code with a new design. Produce a class diagram to represent the restructured code. You are not required to write any program code. (6 marks)
- 两个数组是同一关系的两种表示 → 平行数组,改成独立
Course类 + 1 : 0..*。 - “黑名单”是一种状态,不是子类型:机构可以被拉黑再恢复,类型不该变。
- 6 分看三件事:有没有 Course 类、多重性是否正确、是否去掉了继承。
TrainingProvider(5 个属性 + addCourse/getCourses)1 ◆— 0..* Course;TrainingProvider 1 — 0..1 BlacklistRecord(reason、blacklistedDate、isActive())。4.6 模拟题 5|电商订单(8 分,全关系)
- Customer 1 — 0..* Order;Customer 1 ◇— 0..* Address(聚合:地址可独立存在)。
- Order 1 ◆— 1..* OrderLine(组合:菱形在 Order 端)。
- OrderLine 0..* — 1 Product;Order 1 — 0..1 Coupon。
- Payment «abstract» ← CreditCardPayment / PayPalPayment(泛化,空心三角指向 Payment)。
- OrderLine 同时是 Order 与 Product 的关联类,可在文字里点明(画不画虚线连到关联线都不扣分)。
4.7 模拟题 6|上帝类拆分(6 分)
OrderManager class validates the cart, calculates the price with discounts, saves the order and sends confirmation emails. Refactor the design and draw the resulting class diagram. (6 marks)OrderManager 一个类同时负责校验购物车、算价与折扣、保存订单、发送确认邮件。请重构并画出类图。(6 分)OrderValidator、PriceCalculator、OrderRepository、Notifier,OrderController 只负责编排,四条依赖箭头指向四个协作者。4.8 模拟题 7|纯文字:把场景翻译成类与多重性
| 关系 | 多重性 | 说明 |
|---|---|---|
| Department — Doctor(出诊) | * — * | 医生可跨科室,M:N,需要关联类(如 Assignment)才能放“出诊时间” |
| Department — Doctor(主任) | 1 — 1 | 可用角色名 headDoctor 区分同一条关联 |
| Patient — Appointment | 1 — 0..* | 病人多次预约 |
| Appointment — Doctor | 0..* — 1 | 每次预约一名医生 |
两个不同语义的关联(出诊 / 主任)在同一对类之间出现时,务必用角色名(role name)区分,否则读者无法判断哪条是哪条。
4.9 常见错误
| 错误 | 后果 |
|---|---|
| 缺多重性,或写在同一端 | 每题扣 1–2 分 |
| 组合菱形画在“部分”端 | 符号分 |
| 实现画成实线(与泛化混淆) | 符号分 |
| M:N 不拆关联类 | 结构分(尤其当关联有属性时) |
| boundary/control 也写属性 | 分层理解分 |
| 把数据库表名当类名 | 命名不规范 |
4.10 自检清单
- 每个类都是业务名词,三栏齐全(若题目说不要求属性方法可省)。
- 每条关系两端都有多重性;菱形在整体端;三角指向父/接口。
- M:N 有中间类;同对类多条关联时有角色名。
- 可见性统一;抽象类与接口有标记。
5 · 多态设计 Polymorphism by Design
卷面位置:真题 Q3(6 分)。预算 12 分钟。这题不考画图技巧,考“你懂不懂依赖抽象”。
5.1 题眼长什么样
只要题干里出现下面任何一种说法,就是在考多态:
- “the system needs to be flexible to cater for different … in the future”
- “besides X, it could be Y or Z offered by a different vendor”
- “minimises system changes due to incorporating …”
对应的答案结构永远是三件套:一个接口 + 多个实现 + 客户端只持有接口类型。换供应商时只新增一个类,客户端一行不改(开闭原则)。
| 要素 | 本题 | 缺了会怎样 |
|---|---|---|
| 接口 | IChatbot,只声明 sendQuery() : String | 客户端必须认识每个具体类 |
| 多个实现 | GPTChat、GeminiChat、DeepSChat | 无法证明“可替换” |
| 客户端持接口 | AskMatildaControl 的字段 - chatbot : IChatbot | 依赖具体类,换厂商要改代码 |
5.2 例题|真题 Q3:Ask Matilda(6 分)
Currently the team is considering GPTChat, developed by an external vendor. During prototyping everything looks fine. However, there is a directive: the system needs to be flexible to cater for different chatbots in the future (e.g. GeminiChat, DeepS chat from another vendor).
This translates to a non-functional requirement that the design be flexible enough to plug in different chatbots’ APIs. By leveraging the OO principle of polymorphism, design the use case “Ask Matilda” to minimise system changes when incorporating different chatbots. Show your design with class and/or sequence diagram(s). You are not required to model the interaction with the database. (6 marks)
- “flexible / different chatbots / minimise changes” 三个词叠加,说明必须引入抽象。
- 最小改动的判据:新增一个厂商时,只有新类是新增的,控制类与界面类都不动。
- 画类图即可拿满分;若加时序图,只需画出
Control → IChatbot的调用(运行时绑定到具体实现),不必展开三家实现。
| 类/接口 | 构造型 | 内容 |
|---|---|---|
| FormAskMatilda | «boundary» | enterQuestion(q)、displayReply(msg) |
| AskMatildaControl | «control» | - chatbot : IChatbot;askQuestion(q)、setChatbot(b)、selectChatbot(type) |
| IChatbot | «interface» | + sendQuery(query : String) : String |
| GPTChat / GeminiChat / DeepSChat | 类 | 各自实现 sendQuery() |
关系:Form — Control(关联);Control → IChatbot(关联 1—1);三个厂商类 ⇢ IChatbot(实现,虚线 + 空心三角)。
一句话理由(可直接抄):The control class depends on the abstraction IChatbot; adding a new chatbot vendor requires only a new implementing class, so the design is closed for modification but open for extension.
5.3 模拟题|支付渠道可插拔(6 分)
| 元素 | 内容 |
|---|---|
| 接口 | IPaymentGateway:+ authorize(amount : Money) : AuthResult、+ capture(txnId) : boolean |
| 实现 | StripeGateway、PayNowGateway、AlipayGateway |
| 客户端 | CheckoutControl 持有 - gateway : IPaymentGateway,只调接口方法 |
| 关系 | 三个实现 ⇢ IPaymentGateway(实现);CheckoutControl → IPaymentGateway(关联 1—1) |
理由句:Because the checkout code holds only the interface type, a new gateway is added as a new class and neither the control nor the templates need to change.
5.4 常见错误
| 错误 | 后果 |
|---|---|
| 只画三个具体类,没有接口 | 0 分(没有多态) |
| 有接口但客户端字段写成具体类 | 扣核心分 |
| 用继承父类代替接口,且父类带实现 | 可接受但不推荐,可能扣 1 分 |
| 实现关系画成实线 | 符号分 |
| 只画图不写理由 | 6 分里“说明”那 1 分没了 |
6 · 坏味道与重构 Code Smells & Refactoring
卷面位置:真题 Q4a(6 分,纯文字)/样卷 Q3(10 分,文字 + 图)。预算 8 / 15 分钟。这是全卷性价比最高的分。
6.1 专业名词总表(必须按英文名写)
| 英文名 | 中文 | 识别信号 | 常用手法 |
|---|---|---|---|
| Refused Bequest | 拒绝继承的遗产 | 子类重写父类方法却空实现 / 返回 null | Replace Inheritance with Delegation;Extract Superclass |
| Parallel Arrays | 平行数组 | 两个数组靠下标一一对应 | Extract Class(换成对象集合) |
| Duplicate Code | 重复代码 | 两处几乎相同的逻辑 | Extract Method;Pull Up Method |
| Long Method | 过长方法 | 一个方法几十行、做多件事 | Extract Method |
| God Class | 上帝类 | 一个类什么都管 | Extract Class;Move Method |
| Feature Envy | 依恋情结 | 方法大量访问别的类的数据 | Move Method |
| Data Clumps | 数据泥团 | 几个字段总是一起出现 | Extract Class |
| Primitive Obsession | 基本类型偏执 | 用 String/int 表示金额、日期、状态 | Replace Primitive with Object |
| Type Code / Switch Statements | 类型码 / 分支语句 | 用字符串或整数表示类型,到处 if/switch | Replace Type Code with Enum;以多态取代条件 |
| Lazy Class | 冗赘类 | 一个类几乎没做事 | Inline Class |
| Shotgun Surgery | 霰弹式修改 | 改一个需求要动十几个文件 | Move Method;Inline Class |
| Inappropriate Intimacy | 过度的亲密关系 | 两个类互相访问私有细节 | Move Method;Extract Class |
| Message Chains | 过长的消息链 | a.getB().getC().getD() | Hide Delegate |
| Speculative Generality | 夸夸其谈通用性 | 为“将来可能需要”加的抽象 | Collapse Hierarchy;Inline Class |
6.2 重构手法总表
| 中文 | 英文 | 什么时候用 |
|---|---|---|
| 提炼类 | Extract Class | 一个类承担了多个职责;平行数组 |
| 提炼父类 | Extract Superclass | 两个子类有大量重复成员 |
| 提炼方法 | Extract Method | Long Method / Duplicate Code |
| 上移方法 / 字段 | Pull Up Method / Field | 共有行为在子类里重复 |
| 下移方法 / 字段 | Push Down Method / Field | 只有部分子类用得到 |
| 移动方法 | Move Method | Feature Envy |
| 以委托代替继承 | Replace Inheritance with Delegation | Refused Bequest |
| 以关联代替继承 | Replace Inheritance with Association | 用继承表达“状态” |
| 以多态取代条件 | Replace Conditional with Polymorphism | Switch Statements |
| 以枚举取代类型码 | Replace Type Code with Enum | Primitive Obsession |
| 内联类 | Inline Class | Lazy Class |
6.3 答题三句式(任何坏味道题都能套)
① The code smells of <Smell Name>: <一句话描述现象>.
② As a result, <后果:契约被破坏 / 数据易错位 / 难以扩展 / 重复维护>.
③ Action: apply <Refactoring Technique> — <一句话说清改成什么结构>.
6.4 例题 1|真题 Q4a:TrainingProvider 的两条坏味道(6 分)
Smell 1 — Parallel Arrays. courseId[] and courseTitle[] express one 1-to-many relationship through matching indexes, so any insertion or deletion must update both arrays consistently and the compiler cannot detect a mismatch; no course-level attribute (fee, duration) can be added without creating yet another array.
Action: apply Extract Class — introduce a Course class and replace both arrays with List<Course>, giving TrainingProvider 1 : 0..* Course.
Smell 2 — Inheritance misuse (Refused Bequest). BlacklistedTrainingProvider extends TrainingProvider, although being blacklisted is a status, not a subtype: the subclass inherits the course arrays and the “offer courses” behaviour it must not use, and because a status can change (blacklisted → lifted), the object would have to be destroyed and recreated as another class, losing its identity and existing associations.
Action: apply Replace Inheritance with Association — keep one TrainingProvider type and attach a BlacklistRecord (reason, date) with a 0..1 association; the status then lives in data, not in the type hierarchy.
6 分构成:两条命名 2 + 两条后果 2 + 两个动作 2。
6.5 例题 2|样卷 Q3:Project / SubContractedProject(10 分)
public class Project { private List<String> members; private String manager; public void addMember(String m){ members.add(m); } public String removeMember(String m){ members.remove(m); return m; } … }public class SubContractedProject extends Project { @Override public void addMember(String m){ /* Do nothing */ } @Override public String removeMember(String m){ return null; } private String subContractedCompany; private String contactPerson; }(a) Identify a Bad Code Smell and the Refactoring Techniques that can be used to improve the design.
(b) Modify the design according to the refactoring technique identified in part (a). It is not required to modify the code. (10 marks)
addMember() 改成空实现、removeMember() 返回 null。(a) 指出一个坏味道与可用的重构手法;(b) 按该手法修改设计(不要求改代码)。(10 分)
- 决定性证据是“重写成空实现/返回 null”——子类拒绝了继承来的职责,标准名字是 Refused Bequest。
- 案例自己给了原因:人力由分包公司提供。这说明该职责本来就放错了层,应该只留在内部项目上。
- 手法组合:Extract Superclass(把共有状态上提)+ Move Method(把成员管理下移到
InHouseProject)。也可以用 Replace Inheritance with Delegation。 - (a) 与 (b) 必须一致:文字说提取父类,图里就必须出现抽象父类,不能还是原来的继承。
Bad Code Smell: Refused Bequest. SubContractedProject inherits addMember() and removeMember() from Project but overrides them to do nothing / return null. The inherited contract is therefore broken: a client holding a Project reference cannot rely on these methods when the runtime object is a sub-contracted project, which violates the Liskov Substitution Principle and hides a real business rule (manpower is supplied by the sub-contractor).
Refactoring techniques: (1) Extract Superclass — pull the shared state and behaviour (name, manager, projectDuration, rate, effortRequired, addManager()) up into an abstract Project; (2) Move Method (a form of Replace Inheritance with Delegation) — move addMember()/removeMember() and the members list down into InHouseProject, so that no class inherits a method it must refuse.
| 类 | 内容 |
|---|---|
«abstract» Project | name、manager、projectDuration、rate、effortRequired;addManager() |
InHouseProject | members : List<Member>;addMember()、removeMember() |
SubContractedProject | subContractedCompany、contactPerson;getCompany()、getContactPerson() |
| 关系 | 两个子类 ——▷ Project(泛化,实线 + 空心三角指向父) |
6.6 模拟题 1|一段代码,找出两个坏味道(6 分)
public void printInvoice(Customer c, List<Item> items) {
double total = 0;
for (Item i : items) { total += i.getPrice() * i.getQty(); }
if (c.getType().equals("VIP")) { total = total * 0.9; }
double tax = total * 0.09;
double grand = total + tax;
System.out.println("======= INVOICE =======");
for (Item i : items) {
System.out.println(i.getName() + " x" + i.getQty()
+ " = " + (i.getPrice() * i.getQty()));
}
System.out.println("Grand Total: " + grand);
}
| # | Smell | 证据 | 手法 |
|---|---|---|---|
| 1 | Long Method | 一个方法里做计算、打折、计税、格式化、输出 | Extract Method(calculateTotal / calculateTax / applyDiscount / printLines) |
| 2 | Feature Envy + Type Code | c.getType().equals("VIP") 向 Customer 要类型字符串 | Move Method(→ Customer.isVip())+ Replace Type Code with Enum |
| 加分 | Duplicate Code | 明细里又算了一遍 price * qty | Extract Method → Item.getSubtotal() |
6.7 模拟题 2|反向题:给重构后的图,说原来的问题(6 分)
OrderController delegates to OrderValidator, PriceCalculator, OrderRepository and Notifier. State which smell the original single-class design most likely had, and why splitting it improves maintainability. (6 marks)OrderController 把职责委派给校验、算价、仓储、通知四个类。请指出原始“单类”设计最可能有的坏味道,并说明拆分为何提升可维护性。(6 分)The original class most likely suffered from God Class (with Long Method inside): one class validated input, calculated prices and discounts, persisted the order and sent notifications, so it had several reasons to change.
Splitting it with Extract Class and Move Method gives each collaborator a single responsibility: pricing rules can change without touching persistence; the validator can be unit-tested in isolation; the controller becomes short and readable. It also removes Duplicate Code if more than one entry point needed the same calculation.
6.8 常见错误
| 错误 | 后果 |
|---|---|
| 只说“代码重复、可读性差”,不写标准名 | 命名分全丢 |
| 只命名不写后果 | 每条丢 1 分 |
| 把 Refused Bequest 说成 Duplicate Code / Lazy Class | 方向性错误 |
| 重构手法与坏味道不对应(如用 Extract Method 修继承) | 失配扣分 |
| 样卷题 (a) 说提取父类,(b) 图里还是原继承 | 两问不一致,重扣 |
6.9 自检清单
- 用了标准英文名词(Refused Bequest / Parallel Arrays / God Class …)。
- 每条坏味道都有“现象→后果→手法”三段。
- 文字答案与图答案说的是同一件事。
- 重构后的图里不再出现空实现、返回 null 的覆盖方法。
7 · 数据驱动设计:DDPP 表
卷面位置:真题 1a(6 分)。预算 12 分钟。这是 Section A 的“题眼”——1c 选哪两个用例、1d 画什么屏幕,都由它决定。
7.1 四层到底在问什么
| 层 | 英文(卷面用词) | 它回答的问题 | 典型数据 |
|---|---|---|---|
| 描述性 | Descriptive — understand what happened | 过去发生了什么 | 历史记录、事件日志、实际 vs 计划 |
| 诊断性 | Diagnostic — why something happened | 为什么发生 | 原因分类、根因分析、相关性 |
| 预测性 | Predictive — what could happen next | 接下来可能怎样 | 概率、趋势、预警阈值 |
| 指导性 | Prescriptive — what should happen | 应该怎么做 | 建议动作、备选方案、自动触发 |
课件里的表格列是:Types of Analytics | Analytics tool and data required | Business objective / purpose。考试照这三列画就不会跑偏。
7.2 例题|真题 1a:VoyageLink 的延误预测(6 分)
“He also faces challenges when there are occasional disruptions in the shipping routes due to weather condition, conflicts in the regions, etc. He will have to accept a longer delivery time for the cargos or make last minute change of route which is usually very expensive. His manager expects him to plan carefully and avoid such disruptions, but Danny finds it difficult as he is unable to predict what will happen next.” (6 marks)
- 痛点里的关键词是 unable to predict → 重点落在 Predictive 与 Prescriptive 两层,Descriptive/Diagnostic 是它的数据地基。
- 四层必须层层递进,不能都写成“分析延误数据”。判分看“四行是否各说一件事”。
- 数据要落到这个案例的具体对象:船期、航线、港口、改航成本、天气与地缘事件。
| Types of Analytics | Analytics tool and data required | Business objective / purpose |
|---|---|---|
| Descriptive Understand what happened | 历史航次记录:计划 vs 实际到港时间、中断事件日志(天气/港口拥堵/地缘冲突)、每次改航的实际成本 | 建立“延误—成本”的事实基线,让管理层看到问题的规模 |
| Diagnostic Why something happened | 中断原因分类与归因数据、按航线/季节/港口的延误分布、船公司与航线的历史准点率 | 找出哪类原因、哪条航线最常见,从而知道该在哪个环节干预 |
| Predictive What could happen next | 天气与地缘风险数据源、港口拥堵指数、船期动态、机器学习延误模型(输出延误概率与预计天数) | 在装船前/航行中提前预警,把“被动接受”变成“提前知道” |
| Prescriptive What should happen | 备选航线与舱位数据、改航成本模型、订舱平台实时价格;规则引擎/优化算法生成建议 | 自动推荐最优改航或改期方案并通知买家、清关与运输方,把损失降到最低 |
7.3 模拟题 1|Loving Care 的预约协调(6 分)
| Types of Analytics | Analytics tool and data required | Business objective |
|---|---|---|
| Descriptive | 历史预约记录、实际出诊记录、取消与爽约记录、每位病人平均等待天数 | 看清当前的排期与爽约规模 |
| Diagnostic | 爽约原因、按团队/时段/区域的预约分布、改期次数 | 找出排期最紧张的组合,定位瓶颈 |
| Predictive | 病人历史预约行为、季节性需求、团队可用时段预测 | 预测某周的上门需求与团队负荷,提前排班 |
| Prescriptive | 规则引擎:按固定团队 + 地理邻近 + 时段冲突自动推荐候选时段 | 把“打电话逐个确认”变成系统给出 2–3 个可选项,一键确认 |
7.4 模拟题 2|健身房续费与流失(6 分)
| Types of Analytics | Analytics tool and data required | Business objective |
|---|---|---|
| Descriptive | 出入场刷卡记录、课程预约与到场率、续费记录 | 量化“沉默会员”的比例 |
| Diagnostic | 按会员类型/时段/教练统计的到场频率变化、流失前的行为模式 | 找出流失前 30 天的共同行为 |
| Predictive | 流失倾向模型(连续 N 天未到场 + 课包即将到期 = 高风险) | 提前两周识别高风险会员 |
| Prescriptive | 自动触发:推送 1 对 1 私教体验券、教练回访任务清单 | 在流失前完成干预,提高续费率 |
7.5 常见错误
| 错误 | 说明 |
|---|---|
| 四层都写“分析历史数据” | 层次没递进,最多拿 2 分 |
| 只写技术(“用 AI、用大数据”) | 题目要的是“需要什么数据”,技术只是修饰 |
| 不落到案例对象 | 写成通用模板,考官看不出你读了案例 |
| Prescriptive 写“生成报表” | 报表是 Descriptive/Diagnostic,不是指导性 |
8 · 界面设计与隐喻 Screen Design & Metaphors
卷面位置:真题 1d(4 分)/样卷 1c(4 分)。预算 10 分钟。分值不大,但几乎人人丢一半——因为只画框不说隐喻。
8.1 什么叫隐喻
课件原话:“real world metaphors to improve conceptual model design”,并且明确说——隐喻不一定是漂亮的图片,用户天天在用的纸质表单也算隐喻。它的作用是让用户把已有心智模型直接搬到界面上,不用学新规则。
8.2 可用隐喻清单
| 隐喻 | 把什么映射成什么 | 适用场景 |
|---|---|---|
| 日历 Calendar | 时间 → 格子;可预约性 → 格子颜色 | 预约、排班、课程表 |
| 座位图 Seat map | 号源 → 座位;已占 → 红色 | 挂号、选座、舱位 |
| 书架 Bookshelf | 分类 → 层;条目 → 书脊 | 内容库、库存、档案 |
| 仪表盘 Dashboard | 关键指标 → 表盘/灯号 | 运营监控、预警 |
| 交通灯 Traffic light | 状态 → 红/黄/绿 | 合规、库存、健康度 |
| 购物车 Cart | 待结算项 → 车内物品 | 电商、报名 |
| 看板 Kanban | 流程阶段 → 列;任务 → 卡片 | 审批、工单 |
| 纸质表单 Form | 现有单据 → 同版式电子表单 | 报销、报关、登记 |
8.3 答题结构(4 分的三段)
- 一句话说清映射:“用 seat map 隐喻号源,绿色可约、红色已满,用户像选座位一样选时段。”
- 画 wireframe:只要方框 + 标签 + 3–4 个功能区,不必精美;标出“这里是日历”“这里是号源网格”。
- 说明为什么合适:结合案例角色(Jane、Danny)的使用场景,一句即可。
8.4 例题|真题 1d:支持 DDPP 的屏幕(4 分)
- 1a 选的是“监控与预测 + 处理与改航”,所以屏幕是航线风险看板,不是搜索页。
- 四类分析要在同一屏上各有位置:历史准点率(描述)、原因分布(诊断)、延误概率(预测)、建议改航(指导)。
- 隐喻用“交通灯 + 航线条”最自然:绿=准点、黄=可能延误、红=已中断。
| 区域 | 内容 | 对应的分析层 |
|---|---|---|
| 顶部风险条 | 每条航线一个色块(绿/黄/红),悬停显示延误概率 | Predictive |
| 左栏:历史 | 该航线过去 12 个月计划 vs 实际到港曲线 | Descriptive |
| 中栏:原因 | 按天气/港口/地缘分类的延误原因条形图 | Diagnostic |
| 右栏:建议 | 备选航线卡片 + 预计成本差 + “一键改航”按钮 | Prescriptive |
隐喻句:We use a traffic-light metaphor for route status (green on time, amber at risk, red disrupted) so that Danny can scan dozens of routes at a glance without reading numbers.
8.5 模拟题 1|医院预约界面(4 分)
8.6 模拟题 2|图书馆运营仪表盘(4 分)
8.7 常见错误
| 错误 | 后果 |
|---|---|
| 只画界面不说隐喻 | 4 分里“隐喻”那 2 分没了 |
| 隐喻与业务无关(画个月亮装饰) | 不算隐喻,不加分 |
| 屏幕与 1a/1b 的用例不对应 | 内容分 |
| 画成完整 UI 稿(配色、图标) | 浪费时间,评分只看结构 |
9 · 测试用例与测试数据 Test Cases & Test Data
卷面位置:真题 1e(4 分)。预算 8 分钟。两套卷子都放在 Section A 末尾,很多人最后 10 分钟才动笔,结果只写了一条“正常流程”。
9.1 三个术语
| 术语 | 含义 | 答题时怎么用 |
|---|---|---|
| Test case | 一个“输入 + 前置条件 + 步骤 + 预期结果”的组合 | 一行一条,编号 TC1、TC2 |
| Test data | 喂给这些用例的具体取值 | 表里写实际值(港口名、日期、金额) |
| Equivalence partitioning | 把输入划成“等价类”,每类取一个代表 | 正常 / 无效 / 边界 |
| Boundary value analysis | 取边界及其两侧 | 金额 500、499、501;日期当天、前一天 |
9.2 设计顺序
- 看界面(题目会给截图),列出输入项:出发港、目的港、日期、筛选条件。
- 对每个输入划分等价类:有效、无效、边界、空。
- 组合出 2–3 条测试用例:正常命中、无结果/空态、边界或异常。
- 给每条配一组具体数据,并写清预期结果(含界面提示文案)。
9.3 例题|真题 1e:航线搜索界面(4 分)
| ID | 前置条件 | 测试步骤 | 测试数据 | 预期结果 |
|---|---|---|---|---|
| TC1 | 已登录,存在可用航线 | 选择出发港 → 目的港 → 日期 → 点击 Search Routes | Origin = Shanghai;Destination = Long Beach;Date = 2026-10-12 | 列表显示 ≥1 条航线,含出发/到达与价格;Buy Now 可点击 |
| TC2 | 已登录,该组合无航线 | 同上,选择无航线的组合 | Origin = Shanghai;Destination = Rotterdam;Date = 2026-10-12 | 显示空态 “No routes found”,不出现 Buy Now;条件可修改 |
加分写法:再补一句边界说明——日期取“当天”与“当天 +1”时,若系统允许当天出发,则两条都应可搜索;若不允许,需给出提示。这样体现 boundary value analysis。
9.4 模拟题 1|登录界面(4 分)
| ID | 步骤 | 数据 | 预期 |
|---|---|---|---|
| TC1 | 输入有效账号密码,点击 Sign in | alice / demo123 | 跳转首页,显示用户名 |
| TC2 | 输入有效用户名 + 错误密码 | alice / wrong999 | 停留登录页,提示 “Invalid username or password”,不泄露账号是否存在 |
加分:加一条空字段用例(两个字段都空 → 前端提示必填),以及“密码字段是否掩码”的界面检查。
9.5 模拟题 2|金额边界(4 分)
| ID | 数据 | 预期 |
|---|---|---|
| TC1(边界内) | Amount = 500 | 保存成功,不需要审批(阈值取“大于 500”才审批) |
| TC2(越界) | Amount = 5001 | 拒绝提交,提示金额上限 S$5,000 |
| 补充 | 501 / 5000 / 0 / 空 | 501 触发审批;5000 通过;0 与空被拒 |
9.6 常见错误
| 错误 | 后果 |
|---|---|
| 两条用例其实测的是同一件事 | 只算一条 |
| 数据写“正常值/异常值”,没有具体值 | “测试数据”那 2 分丢一半 |
| 没有预期结果 | 用例不成立 |
| 只测正常路径 | 看不出等价类/边界值能力 |
10 · 附录:术语、符号、时间与清单
10.1 英文术语总表
| 类别 | 中文 | 英文(卷面拼写) |
|---|---|---|
| 需求与用例 | 参与者 | Actor |
| 系统边界 | System Boundary | |
| 用例 | Use Case | |
| 包含 / 扩展 | «include» / «extend» | |
| 泛化 | Generalization | |
| 基本事件流 | Basic Flow of Events | |
| 非功能需求 | Non-functional Requirement | |
| 客户旅程图 | Customer Journey Map | |
| 活动图 | 泳道 / 分区 | Swimlane / Partition |
| 初始节点 / 结束节点 | Initial Node / Activity Final Node | |
| 动作 | Action (Activity) | |
| 判断 / 汇合 | Decision Node / Merge Node | |
| 监护条件 | Guard Condition | |
| 对象节点 | Object Node | |
| 并发分支/汇合 | Fork / Join | |
| 时序图 | 生命线 | Lifeline |
| 同步消息 | Synchronous Message | |
| 返回消息 | Return Message | |
| 激活条 | Activation Bar | |
| 边界类 | Boundary Class (UI Class) | |
| 控制类 | Control Class | |
| 实体类 | Entity Class | |
| 分析模型 | Analysis Model | |
| 类图 | 属性 / 操作 | Attribute / Operation |
| 多重性 | Multiplicity | |
| 关联 | Association | |
| 聚合 / 组合 | Aggregation / Composition | |
| 实现 | Realization | |
| 依赖 | Dependency | |
| 关联类 | Association Class | |
| 抽象类 / 接口 | Abstract Class / Interface | |
| 多态 / 开闭原则 | Polymorphism / Open-Closed Principle | |
| 重构 | 代码坏味道 | Code Smell |
| 重构 | Refactoring | |
| 拒绝继承的遗产 | Refused Bequest | |
| 平行数组 | Parallel Arrays | |
| 上帝类 | God Class | |
| 提炼类 / 提炼父类 / 提取方法 | Extract Class / Extract Superclass / Extract Method | |
| 测试 | 测试用例 / 测试数据 | Test Case / Test Data |
| 等价类划分 | Equivalence Partitioning | |
| 边界值分析 | Boundary Value Analysis | |
| 预期结果 | Expected Result | |
| 前置条件 | Precondition | |
| 分析 | 描述性 / 诊断性 | Descriptive / Diagnostic |
| 预测性 / 指导性 | Predictive / Prescriptive | |
| 隐喻 | Metaphor | |
| 线框图 | Wireframe |
10.2 符号速查
| 符号 | 名称 | 用在哪 | 一句话 |
|---|---|---|---|
| 实线无箭头 | Association | 用例图 / 类图 | actor—用例、类—类 |
| 虚线 + 开口箭头 | «include» / «extend» / Dependency | 用例图 / 类图 | 必做/可选;依赖 |
| 实线 + 空心三角 | Generalization | 用例图 / 类图 | 指向父 |
| 虚线 + 空心三角 | Realization | 类图 | 指向接口 |
| 实心菱形 | Composition | 类图 | 在整体端,部分随整体亡 |
| 空心菱形 | Aggregation | 类图 | 在整体端,部分可独立 |
| 圆角矩形 | Action | 活动图 | 动词开头 |
| 菱形 | Decision / Merge | 活动图 | 出边必须有 guard |
| 矩形 + [state] | Object Node | 活动图 | 实体状态变化 |
| 实心圆 / 牛眼 | Initial / Final | 活动图 | 起止 |
| 方框(顶部长条) | Lifeline | 时序图 | :ClassName |
| 窄长条 | Activation Bar | 时序图 | 对象活跃期间 |
10.3 150 分钟怎么分(真题结构)
| 时段 | 任务 | 产出 |
|---|---|---|
| 0–30 | 读题期(只读不写) | 把四道题要交的图列成清单;抄下案例里所有角色与外部系统 |
| 30–45 | 1a DDPP 表 | 四行三列 |
| 45–65 | 1b 用例图 | 12 个用例 + 7 个 actor |
| 65–90 | 1c 两张活动图 | 各 6–8 步 |
| 90–100 | 1d 屏幕 + 隐喻 | wireframe + 一句隐喻说明 |
| 100–110 | 1e 测试用例 | 2 用例 + 1 组数据 |
| 110–140 | Q2 时序图 | 20–25 条消息 |
| 140–150 | Q3 多态 + Q4a/b | 类图 + 两段文字 + 重构类图 |
| 150–165 | 检查与上传 | 编号、命名、导 PDF、按 Section 上传 |
如果题量是样卷结构(3 题),把 Section A 的三问按 20/25/10 分配,Section B 按 25/25/20 分配,留 15 分钟检查。
10.4 开卷只准纸质:带什么
- 本手册打印件(约 20–30 页 A4,双面)。打印时浏览器会自动去掉侧栏。
- 两页速查卡:符号表 + 英文术语表(可从 §10.1、§10.2 单独打)。
- 一个空白模板页:如果考场允许带自己的图,带 4 张空白模板(用例/活动/时序/类)会省 20 分钟。
- 红笔:用来在读题期圈外部系统与关键词(很多人在这一步漏掉 「system / portal / gateway」)。
10.5 高频失分 Top 10
| # | 失分点 | 丢分 | 补救 |
|---|---|---|---|
| 1 | 用例图漏外部系统 | 2–3 | 读题时专用一笔划“平台/门户/网关” |
| 2 | 时序图没有返回消息 | 2–4 | 每画一条调用立刻补一条虚线 |
| 3 | 活动图没有对象节点 | 2 | 先写实体清单再画图 |
| 4 | 类图多重性缺失/标反 | 1–2 | 每画一条线立刻标两端 |
| 5 | 重构题只命名不写后果 | 2 | 套三句式 |
| 6 | DDPP 四层写成一个意思 | 3 | 写完逐行问“这行和上一行差别在哪” |
| 7 | 屏幕题不说隐喻 | 2 | 先写隐喻句再画框 |
| 8 | 测试数据写“正常值” | 2 | 必须给具体港口/日期/金额 |
| 9 | 多态题客户端依赖具体类 | 3 | 检查字段类型是不是接口 |
| 10 | 画了 login / 报表用例 | 1–2 | 题干有 exclude 就先划掉 |
10.6 最后检查清单(交卷前 5 分钟)
- 每张图都有标题吗?图里命名和案例用词一致吗?
- 用例图:actor 数量 ≥ 3?外部系统 ≥ 2?
- 活动图:三泳道?至少一个 guard?至少两个 [state]?
- 时序图:编号连续?虚线返回 ≥ 5 条?条件分支有 alt?
- 类图:每条线两端都有数字?菱形在整体端?三角指向父?
- 文字题:坏味道有名有姓?DDPP 四层不重复?测试数据是具体值?
- PDF 按 Section 命名并分别上传了吗?