UML系统分析与设计复习:九种图、多重度与职责分配考点速查
简介:这份《UML系统分析与设计复习试题详解》面向准备课程考试、面试复盘及需要夯实建模基础的学生与软件设计初学者,围绕统一建模语言在系统分析与设计中的核心考点组织内容,帮助读者用题目串联关联多重度、组合与聚合、客户与订单的数量关系、顺序图与协作图差异、高内聚、可见性、领域模型等知识点。资源包含1个doc文档,压缩包约132KB,体量精简,便于直接查阅、打印和做短周期集中复习。文档以试题、答案与解析结合的方式展开,并涉及用例图、类图、序列图、GRASP职责分配、设计模式、FURPS需求分类等延伸内容,可用于核对概念理解、梳理常见题型和查漏补缺,也能辅助整理UML图在静态设计与动态交互中的适用场景。已有406人学习,适合希望快速过一遍重点并建立知识框架的学习者。
1. 先立地图:UML 复习到底在考哪几条主线
UML 系统分析与设计的复习试题,翻来覆去就那么几类:认图、读多重度、辨关系、比顺序图和协作图、背统一过程四阶段、套 GRASP 与 GoF 模式。真正拉开差距的不是谁背得多,而是脑子里有没有一张对得上号的地图——九种图分别管哪个视图,四种关系凭什么区分,从用例走到类图中间要跨几步,每一步产出什么制品,错一处又会连带错在哪。
这份笔记按“结构怎么画、行为怎么描、需求怎么落到对象、职责怎么分、哪里最容易翻车、最后怎么自查”的顺序重排了一遍,把散在试题里的知识点归到同一条线上。它更适合已经过了一遍教材、想在做题时快速定位考点的人,而不是从零开始认符号的人。
2. 静态结构:类图、四种关系与多重度的判读顺序
结构图这一块是丢分最集中的地方。原因不在于概念难,而在于几个近义词长得太像:关联和聚集、聚集和组合、泛化和实现,图形记号只差一个菱形是空心还是实心、三角是实线还是虚线,考场上手一抖就写反。更麻烦的是多重度,题目往往用一段业务陈述把数量关系藏在句子里,读错方向就把 1 和 0..* 全调了个个儿。
梳理下来会发现,这一块其实是三层:先认关系,再读数量,最后把关系落到代码上验证一遍。三层过了,类图相关的选择题和画图题基本不会再失分。
2.1 四种关系外加一条支线:依赖、关联、泛化、实现与聚集
UML 里被反复考的基本关系是四种:依赖、关联、泛化、实现。聚集不算第五种,它是关联的一种特殊形态,表示整体与部分;组合又是聚集里更强的那一档,部分的生命周期跟着整体走。这个“四加一”的层次关系一定要先摆正,很多判断题就是拿“聚集是不是一种独立关系”来设套。
| 关系 | 图形记号 | 语义侧重 | 典型场景(虚构示例) | 代码映射 |
|---|---|---|---|---|
| 依赖 | 虚线加开放箭头 | 临时使用,一方变化会影响另一方 | 结算类临时调用计价规则类 | 参数、局部变量、静态调用 |
| 关联 | 实线,可带角色名与多重度 | 长期稳定的结构联系 | 客户与订单 | 成员变量持有引用 |
| 泛化 | 实线加空心三角,指向父类 | 一般与特殊,子类可替换父类 | 会员客户继承客户 | extends |
| 实现 | 虚线加空心三角,指向接口 | 类兑现接口声明的契约 | 某支付类实现支付接口 | implements |
| 聚集 | 空心菱形加实线,菱形在整体端 | 整体与部分,部分可独立存在 | 部门与人员 | 集合持有外部传入对象 |
| 组合 | 实心菱形加实线,菱形在整体端 | 整体与部分,部分随整体消亡 | 订单与订单项 | 集合内部创建并持有 |
判断关系有个很实用的顺序:先看生命周期是否绑定,绑定的往组合靠;再看对象是否从外部传进来,传进来的往聚集或关联靠;最后看是不是纯粹的临时调用,是就往依赖靠。图形题里如果两端都画了多重度、又没有菱形,那就老老实实答关联,别自作聪明往上加聚合。
2.2 多重度:读的方向,和两道反复出现的题
多重度的读法只有一句话:站在一端,问另一端的实例能有几个。书上那句“一个客户提交 0 个或多个订单,一个订单由一个且仅由一个客户提交”,翻译成图就是客户端标 1,订单端标 0..*。对应每个订单实例,存在 1 个客户实例;对应每个客户实例,存在 0 个或多个订单实例。答案落在 B 和 D,两个空的方向是反的,这一点每年都有人写错。
第二类高频题是把多重度藏在“构成”两个字里:类 A 由类 B 的一个实例和类 C 的一个或多个实例构成。看到“构成”“由……组成”,先定组合;菱形画在 A 这一端,因为 A 是整体;B 端标 1,C 端标 1..,数量和文字一一对应。销售实例里那组 a、b、c、d 的填空也是同一套路:先分清谁是整体、谁是明细,再按陈述里的“一个”“多个”往两端填 1 或 1..。
多重度的写法本身也要记准:1 表示恰好一个,0..1 表示可选,0..* 和 * 表示零到多,1..* 表示至少一个,n..m 是区间。写画图题时端点的数字要贴着连线写,别飘在图形中间让别人猜你标的是哪一端。
2.3 四张结构图的分工:类图、对象图、构件图、部署图
静态方面有四张结构图,考法几乎固定:给一句描述,问该用哪张图。类图是最常用的那张,说明系统的静态设计视图;对象图是某一时刻的对象快照,用来表达实例层面的数据结构;构件图对应静态实现视图,管的是源码、可执行体、物理数据库这类实现制品;部署图对应静态实施视图,描述节点、网络布局以及构件在节点上的分布。
| 图 | 视图类型 | 描述对象 | 常见考点句 |
|---|---|---|---|
| 类图 | 静态设计视图 | 类、接口、关系 | “最常用的图”“说明静态设计视图” |
| 对象图 | 静态设计视图或静态过程视图 | 一组对象及其关系 | “某一时刻的快照” |
| 构件图 | 静态实现视图 | 构件及其组织与依赖 | “源码、可执行发布、物理数据库” |
| 部署图 | 静态实施视图 | 节点与构件分布 | “硬件物理拓扑、网络布局” |
对应那道三空的题,答案就是类图、构件图、部署图。这里最容易出错的是把构件图和部署图搞混:构件图管“有哪些可交付的东西”,部署图管“这些东西跑在哪些机器上”。题干里出现节点、网络、物理拓扑,直接锁定部署图。
2.4 落到代码:new 在里面的叫组合,传进来的叫聚合
图形记号记不牢的时候,用代码反推最快。下面这段是同一份领域里两种不同强度的持有关系,注释标出了关键区别。
// 组合:订单项在订单内部创建,生命周期跟着订单走 public class Order { private final List<OrderItem> items = new ArrayList<>(); public void addItem(String sku, int qty) { // new 发生在整体内部,外部拿不到这个对象的创建权 items.add(new OrderItem(sku, qty)); } } // 聚合/关联:订单从外部传入,客户只是持有引用 public class Customer { private final List<Order> orders = new ArrayList<>(); public void addOrder(Order order) { // order 由外部创建后传入,客户消失订单未必消失 orders.add(order); } }逻辑说明很直白:对象的创建权在谁手里,生命周期就归谁管。Order内部new OrderItem(...),订单项不可能脱离订单单独存在,这是组合;Customer只是接收外部已经造好的Order并放进集合,客户和订单各自独立,这是聚合,落到图上就是空心菱形或者干脆只画普通关联。参数上没什么可调的,真正要改的是设计判断:一旦你发现某个“部分”需要在多个“整体”之间共享,那它就不该画成组合。
2.5 封装、可见性与消息:四道基础判断题
除了图和关系,还有一组概念题年年出现,句子很短但很容易含糊过去。封装是一种信息隐藏技术,目的是让对象的定义和实现分离;类里每个对象都是这个类的一个实例;类之间共享属性与服务的机制叫继承;一个对象请求另一个对象为其服务,靠的是发送消息,不是“调用语句”也不是“命令”。
可见性指的是一个对象能够“看到”或者引用另一个对象的能力,它和封装是一体两面:封装挡住外部直接访问内部细节,可见性决定谁能发消息给谁。这两条经常被合成一道简答题,答的时候把“能看到”和“能引用”两个动作都写出来,比只写“可以访问”更稳。
3. 动态行为:顺序图、协作图、SSD 与状态活动图的分工
静态图回答“系统由什么构成”,动态图回答“事情按什么次序发生”。这一块出题的特点是描述性很强、选择题很碎:一句“按时间顺序描述对象间的交互”就要你立刻反应出序列图,一句“强调收发消息的对象的组织结构”就得对上协作图。真正容易混淆的是用例图、状态图、活动图、顺序图、协作图这五张图各自负责哪一段,以及 SSD 到底画不画系统内部。
把这几张图排在同一条时间轴上会清楚很多:用例图站在系统边界外看谁用系统,SSD 站在边界上看外部actor对系统敲了哪几下,顺序图和协作图看系统内部对象之间怎么互相发消息,状态图盯着单个对象的生命周期,活动图盯着一串活动和控制流。
3.1 九种图的两条轴:静态还是动态、结构还是行为
UML 的九种图常被归成五类:用例图、静态图(类图、对象图、包图)、行为图(状态图、活动图)、交互图(顺序图、协作图)、实现图(构件图、部署图)。这个五分法是简答题的标准骨架,先背框架再填细节,不容易漏项。
| 图 | 归类 | 主要职责 | 一句话题眼 |
|---|---|---|---|
| 用例图 | 用例图 | 系统与外部系统、用户之间的交互 | 站在边界外看功能 |
| 类图 | 静态图 | 静态设计视图 | 最常用的图 |
| 对象图 | 静态图 | 实例快照 | 某一时刻的数据结构 |
| 状态图 | 行为图 | 单个对象的状态与转移 | 生命周期 |
| 活动图 | 行为图 | 活动、顺序、并发、工作流 | 控制流程 |
| 顺序图 | 交互图 | 按时间顺序组织的交互 | 时间轴 |
| 协作图 | 交互图 | 强调对象组织结构 | 空间布局 |
| 构件图 | 实现图 | 构件组织与依赖 | 静态实现视图 |
| 部署图 | 实现图 | 节点与构件分布 | 静态实施视图 |
题目里出现“对系统的行为进行组织和建模非常重要”,答案是用例图;出现“给出系统的静态设计视图”,答案是类图;出现“描述系统与外部系统及用户之间的交互”,还是用例图;出现“按时间顺序描述对象间的交互”,直接选序列图。这几句几乎是原话照搬,认句子比认概念更快。
3.2 顺序图与协作图:同一份交互的两种布图
顺序图和协作图描述的是同一件事,只是布图方式不同。顺序图按时间顺序从上往下排,横向是对象,纵向是时间,消息箭头从上到下依次发生,时间关系一眼可见;协作图按空间组织布图,对象之间的连线代表连接,消息挂在连线上,靠消息编号体现先后。
| 对比项 | 顺序图 | 协作图 |
|---|---|---|
| 侧重点 | 交互的时间顺序 | 对象的组织结构与语境 |
| 布图方式 | 按时间纵向展开 | 按空间组织 |
| 时间顺序来源 | 消息箭头的上下位置 | 消息编号 |
| 空间占用 | 水平方向占得多 | 分支少时更紧凑 |
| 增加对象 | 需要重排时间轴 | 插入相对容易 |
| 消息很多时 | 顺序依然清楚 | 编号难读,顺序不明显 |
| 典型用途 | 表示方案、理清事件流 | 详细设计、看对象如何协作 |
优缺点就藏在这张表里:顺序图时间清楚但吃横向空间,协作图加对象方便但消息一多顺序就糊。两者的设计方法也是配套的:先根据系统操作规约画顺序图把事件流捋顺,再转成协作图确认对象之间的连接是否合理,最后配合类图和操作契约写出类代码。转换时注意协作图上的编号必须和顺序图里的箭头顺序对得上,编号一乱,整张图就没法验证。
3.3 SSD:把系统当成一个黑盒来画
SSD 是系统顺序图,画的是外部参与者与系统之间的事件交互。它的要素只有三个:参与者、系统(画成一个整体方框,写系统名)、系统事件(带参数的箭头)。系统内部有哪些对象、怎么分层、调用了哪些方法,统统不画。
那条选择题的答案就在这里:画 SSD 时不对系统的内部结构与功能进行描述。很多人在这题上纠结,是因为平时画顺序图画习惯了,看到图就想往里塞对象。判断标准很简单:SSD 里如果出现了系统内部的对象名,这图就画错了。
以收银场景为例,事件序列可以列成一张表,既方便答题也方便检查遗漏:
| 步骤 | 外部动作 | 系统事件 | 参数 |
|---|---|---|---|
| 1 | 收款员启动一次销售 | makeNewSale() | 无 |
| 2 | 收款员输入商品标识 | enterItem(itemID, quantity) | 商品标识、数量 |
| 3 | 销售结束 | endSale() | 无 |
| 4 | 顾客付款 | makePayment(amount) | 金额 |
SSD 画完之后紧接着就是操作契约:把系统当成提供公共接口的黑盒,公共接口处理输入的系统事件,契约描述的是某个系统操作执行完之后,领域模型中对象状态发生了什么变化。SSD 管“敲了什么”,操作契约管“敲完之后世界变成什么样”,两者一前一后,别混成一张图。
3.4 状态图与活动图:一个管对象的一生,一个管流程怎么走
状态图盯的是一个特定对象,画出它所有可能的状态,以及各种事件引起的状态转移。它描述的是一个状态机,属于动态视图,对接口、类、协作的行为建模特别有用,也常用来描述一个用例实例的生命周期。答题时抓住“特定对象”“状态”“事件触发转移”这三个关键词,基本不会串到别的图上。
活动图是一种特殊的状态图,描述需要做哪些活动、按什么顺序做、哪里并发,以及完成工作要经过哪些步骤。它强调的是对象间的控制流程,对功能建模很重要。高层活动图用来表示需要完成的一组任务,适合分析用例、理解跨多个用例的工作流;低层活动图用来表示某个类方法内部的处理过程。要注意它的边界:活动图不擅长描述动作与对象之间的关系,也不擅长展示对象之间的合作和对象在生命周期内的运转,遇到这类需求还得回到交互图或状态图。
3.5 用例图:参与者在框外,用例在框内
用例图描述系统与外部系统及用户之间的交互,构图元素就是参与者、用例和它们之间的关系。参与者一定在系统边界之外,哪怕它是另一个系统;用例是系统对外提供的功能单元,不是内部模块。
以打电话为例:参与者是电话用户,用例有“使用电话卡”和“对方付款”两个,两个用例都直接连到同一个参与者,不用在中间加什么“拨号模块”。如果两个用例之间有公共步骤,用包含关系抽出来;某个用例只在特定条件下才发生,用扩展关系。用 include 和 extend 的方向别写反:包含是基础用例指向被抽出的公共用例,扩展是扩展用例指向被扩展的用例。
4. 需求到职责:用例模型、领域建模与 GRASP 的分层落点
从这一章开始,题目从“认图”转向“说理”。前面的图是制品,这里要回答的是制品怎么来:需求怎么分类、概念类怎么找、领域模型长什么样、统一过程的四个阶段各干什么、职责该分给谁。这一段的知识点在试卷上多以简答和填空出现,看起来是背,其实内部有很强的因果链——需求决定领域模型,领域模型决定职责分配,职责分配决定最终代码的形状。
最容易忽略的是这中间每一步的产出物名称。很多人能说出“要做领域建模”,却答不出领域模型是概念类的集合、不是软件部件模型;能背出四个阶段,却把“定义大多数需求”塞进初始阶段。这类失分最冤。
4.1 用例模型:参与者、场景与三种描述详略
用例是一个描述性的文档,描述一个参与者使用系统完成某个业务过程时的事件发生顺序。它描述的是系统使用过程,属于功能需求,不描述系统内部如何工作,只定义系统的责任、说明系统必须做什么。场景是用例里的一条具体路径,参与者是与系统交互的外部角色。
用例的描述分三档:Brief 只写一段摘要,Casual 是松散的多段格式,Fully dressed 则包含前置条件、后置条件、主成功场景、扩展场景等完整结构。考试里如果问“如何描述用例”,把这三档名字点出来,再补一句“越正式的结构越适合需求评审和高风险用例”,比空谈“要写清楚”得分高。
用例模型是需求工作的重要制品,用例图则是用 UML 表达用例及用例之间关系的方式。分清“模型是制品、图是表达”,简答题的层次立刻清楚。
4.2 FURPS 与愿景文档:需求分类的记法
FURPS 是需求分类的常用框架,五个字母分别对应功能、可用性、可靠性、性能、可维护性。功能需求是主体,后四项属于非功能需求,答题时最好各举一个虚构例子,比如“支持退货”是功能,“收银界面三步内完成结账”是可用性,“断网时本地缓存不丢单”是可靠性。这样写比只列五个中文词更有说服力。
愿景文档的内容也要能说出来:问题说明、主要的高层目标、风险承担者需要解决的问题、简要的功能需求描述、以及功能之外的其他需求。它出现在初始阶段,作用是把范围和目标先框住,防止项目一开始就跑偏。
4.3 概念类识别的两条策略与领域建模四步
找概念类有两条策略:一是用概念类类别表逐项对照,看业务里有没有对应的事物;二是从需求文字里标识名词短语,把名词和名词短语挑出来做候选。前者系统但容易僵化,后者灵活但容易漏,实战里两条一起用最稳。
以收银场景为例,从陈述里能挑出的概念类包括顾客、POS 收款台、收款员、销售、商品标识、商品、商品说明。注意“商品标识”和“商品”是两个东西,前者是编码,后者是实体,这种区分恰恰是命题人喜欢考的地方。
领域建模的步骤可以固化成四步:列出候选概念类、画出领域模型图、必要时加入概念类之间的关联、必要时加入概念类的属性。顺序不能反,先把类定下来再谈关联,关联的多重度才有意义。
提示:领域模型是一组表示真实世界中概念类的模型,不是软件部件模型。选择题里把“概念模型”选出来就对了,看到“软件部件”“设计模型”直接排除。
4.4 UP 四阶段与核心工作流:谁干什么,别记反
统一过程分四个阶段:初始、细化、构造、提交。初始阶段做的是编制简要的愿景文档、建立业务案例、确定范围、粗略评估成本;细化阶段细化愿景文档、迭代地实现核心架构、解决高风险问题、定义大多数的需求和范围、进一步评估成本;构造阶段迭代实现系统其余部分并准备部署;提交阶段做 beta 测试和部署。
| 阶段 | 主要工作 | 高频陷阱 |
|---|---|---|
| 初始 | 愿景文档、业务案例、确定范围、粗略评估成本 | 误以为要在这里定完需求 |
| 细化 | 定义大多数需求和范围、核心架构、解决高风险 | 把“定义大多数需求”记到别的阶段 |
| 构造 | 迭代实现其余部分、准备部署 | 误以为构造阶段才开始定架构 |
| 提交 | beta 测试、部署 | 与构造阶段的边界模糊 |
核心工作流是业务建模、需求、设计、实现、测试。UP 的核心思想可以概括成几条:短时间盒的迭代式开发,过程中不断调整,早期迭代解决高风险高价值问题,持续与用户衔接拿反馈,早期构造核心体系结构,早期进入实现和测试做质量检验,用用例驱动并以 UML 可视化建模,仔细管理需求并控制变更。
增量开发有两层意思:一是把一个复杂的用例拆到多次迭代里,一部分一部分实现;二是把所有用例按优先级排进不同迭代。这两句话经常被合成一道简答题,少写一层就少一半分。
4.5 GRASP:五个高频模式,外加一个体系陷阱
GRASP 是通用职责分配原则的模式化表达,考得最多的是五个:信息专家、创建者、低耦合、高内聚、控制器。信息专家回答“职责该分给谁”——分给拥有完成该职责所需信息的那个对象;创建者回答“谁负责 new 一个对象”——谁持有初始化数据、谁记录创建、谁密切使用,谁就是创建者;低耦合回答“如何降低依赖、提高复用”;高内聚回答“如何把复杂度控制在可管理范围”;控制器回答“谁来处理输入的系统事件”。
| 模式 | 解决的问题 | 落地感觉 |
|---|---|---|
| 信息专家 | 分配职责的基本原则是什么 | 谁有数据谁干活 |
| 创建者 | 谁负责创建某个类的新实例 | 谁持有、记录、密切使用 |
| 低耦合 | 如何支持低依赖与复用 | 少互相引用 |
| 高内聚 | 如何把复杂度控制住 | 一个类别揽太多职责 |
| 控制器 | 谁来处理输入的系统事件 | 界面后面加一层接收者 |
高内聚的定义要背准:它是对一个类中各个职责之间相关程度和集中程度的度量,一个类职责高度相关、且完成的工作量不特别巨大,就是高内聚。展开有两层意思:不要让一个类承担太多职责,履职时尽量把部分职责分给更有能力完成的类;不相关的职责不要塞进同一个类。
这里有个经典陷阱:GRASP 之外的选项要能认出来。多态、纯虚构、间接、防止变异都属于 GRASP 家族,而 GoF 是另一套东西,把它混进 GRASP 的选项里就是送分题变成送命题。
4.6 GoF 模式:六个常考的意图
设计模式是经验丰富的面向对象设计者总结出的通用解决方案,按问题和解决方案的结构编纂并命名。考试通常不给代码,只给一句“希望达到某某效果,该用哪个模式”。
| 模式 | 要解决的问题 | 解决方案一句话 |
|---|---|---|
| 单例 | 如何让一个类严格只有一个实例 | 定义返回唯一实例的静态方法 |
| 策略 | 算法或规则频繁变更怎么办 | 每个算法一个类,公共接口可互换 |
| 组合 | 希望像处理原子对象那样处理组合对象 | 组合对象与原子对象实现同一接口 |
| 观察者 | 如何维护对象之间的一致性 | 状态变化时通知所有依赖者并自动更新 |
| 适配器 | 接口不兼容怎么办 | 中间加一层转换,把原接口变成目标接口 |
| 工厂方法 | 创建逻辑集中且可扩展 | 把实例化推迟到子类或工厂中 |
设计过程中的开闭原则也常被带一句:对扩展开放,对修改关闭。它和策略、工厂方法是同一套思路的不同侧面——新增行为靠加类,而不是改老代码。
职责分配落到代码上,最直观的就是下面这段:总价该由谁算,答案不是界面类,而是持有明细的那个类。这就是信息专家的一次具体兑现。
public class Sale { private final List<SalesLineItem> lines = new ArrayList<>(); // 创建者模式:Sale 持有明细集合并记录创建,所以由它 new 明细 public void addLine(ProductSpec spec, int qty) { lines.add(new SalesLineItem(spec, qty)); } // 信息专家:总价所需数据都在 Sale 手里,计算职责就归它 public Money total() { Money sum = Money.zero(); for (SalesLineItem line : lines) { sum = sum.add(line.subtotal()); } return sum; } }addLine里new发生在Sale内部,符合创建者;total遍历自己持有的明细,符合信息专家。如果把这两个方法挪到界面类上,界面就得反过来向Sale索要内部集合,耦合立刻升高,这也是低耦合与高内聚在代码层面的直接体现。
5. 易漏点排查:五处最容易在考场上翻车的地方
题目刷到一定量就会发现,错的总是那几处,而且每次错得都很像。下面这五条是按出错频率排的,每条都给出漏在哪、为什么会漏、怎么补。
5.1 易漏点一:把多重度读成“方法被调用的次数”
易漏点:看到“一个类的实例与另一个类的多个实例相关联”,脑子里冒出“调用次数”“方法个数”这类干扰项。
为什么漏:多重度描述的是实例之间的静态数量关系,而“调用”是运行时的动态行为,两者在中文表述里都可能出现“多个”“次数”。命题人正是利用这个语感做干扰项。
怎么补:读题时强制把句子翻译成“一个 X 实例对应几个 Y 实例”,凡是没有落到“实例数量”的选项一律排除。练习时把每道多重度题的答案写成“X 端 n,Y 端 m”的格式,写不出来说明还没读懂。
5.2 易漏点二:聚集、组合、关联三选一时凭感觉
易漏点:图上菱形一出现就答“聚合”,不管它是空心还是实心;或者看到两个类有关系就写“关联”,漏掉整体部分的语义。
为什么漏:这三个概念的图形差别只有一笔,语义差别却在生命周期上,而多数人记图不记语义。
怎么补:用一句判断句替代图形记忆——“部分能不能脱离整体单独活”。能,是聚集;不能,是组合;根本没有整体部分关系,只是互相知道对方,才是普通关联。再把 2.4 那段 Java 代码默写一遍,new在里面还是外面,比看菱形可靠。
5.3 易漏点三:顺序图与协作图的优缺点说反
易漏点:答“协作图时间顺序清楚”“顺序图节省空间”,正好反了。
为什么漏:两张图都能表达交互,区别只在布图方式,背的时候只记了名字没记“时间轴”和“空间布局”这两个锚点。
怎么补:记一句口决——顺序图吃横向空间换时间清晰,协作图省空间但要靠消息编号找顺序。再补一句用途差异:顺序图多用于表示方案,协作图多用于过程的详细设计。答题时把“时间顺序靠箭头上下位置”和“时间顺序靠消息编号”这两句写上去,基本满分。
5.4 易漏点四:UP 四阶段的职责记串
易漏点:把“定义大多数的需求和范围”写进初始阶段,或者以为核心架构是在构造阶段才搭。
为什么漏:四个阶段的名称顺序好背,但每个阶段的具体动作是并列短语,缺少因果线索,背完就混。
怎么补:给每个阶段配一个动词重心——初始是“框范围”,细化是“定需求、搭骨架、排风险”,构造是“填肉”,提交是“交付”。再记一句:初始阶段只做粗略评估成本,成本的精算和需求的大头都在细化阶段。
5.5 易漏点五:SSD 里画进了系统内部对象
易漏点:画系统顺序图时顺手把领域对象、控制类也画进去,或者在被问“如何对待所涉及的系统”时选了“详细描述内部结构”。
为什么漏:平时画顺序图画的就是对象之间的消息,肌肉记忆太强,一到 SSD 就条件反射。
怎么补:画之前先在纸上画一个方框写“系统”,把参与者放在框外,所有箭头只允许从外指向这个方框,参数写在箭头上。凡是脑子里冒出“这个操作内部调了谁”,立刻停手——那是顺序图和操作契约的活,不是 SSD 的。
6. 复习清单:把九种图和两条主线过成一张自检表
复习到最后阶段,最有效的动作不是再刷一套新题,而是拿一张表把知识点按“能不能一句话说清”过一遍。下面这张自检表是我自己用的版本,左边是考点,右边是必须能脱口而出的那句话,说不出来就回去翻对应章节。
| 考点 | 必须能脱口而出的一句话 |
|---|---|
| 类图 | 静态设计视图,面向对象系统中最常用的图 |
| 对象图 | 一组对象及关系的静态快照 |
| 构件图 | 静态实现视图,管源码、可执行体、物理数据库 |
| 部署图 | 静态实施视图,管节点、网络布局与构件分布 |
| 用例图 | 描述系统与外部系统及用户之间的交互 |
| 顺序图 | 按时间顺序组织对象间的交互 |
| 协作图 | 强调收发消息的对象的组织结构,顺序靠消息编号 |
| 状态图 | 一个特定对象的状态与事件引起的转移 |
| 活动图 | 特殊状态图,描述活动、顺序、并发与工作流 |
| 四种关系 | 依赖、关联、泛化、实现,聚集是关联的特例 |
| 组合与聚集 | 部分能否脱离整体独立存在 |
| 多重度 | 站在一端问另一端有几个实例 |
| FURPS | 功能、可用性、可靠性、性能、可维护性 |
| 领域模型 | 真实世界概念类的模型,不是软件部件模型 |
| 找概念类 | 概念类类别表、标识名词短语 |
| UP 四阶段 | 初始、细化、构造、提交,需求大头在细化 |
| 核心工作流 | 业务建模、需求、设计、实现、测试 |
| GRASP 五常客 | 信息专家、创建者、低耦合、高内聚、控制器 |
| 高内聚 | 职责相关且集中,不把不相关的职责塞进同一个类 |
| SSD | 系统当黑盒,只画参与者、系统、系统事件 |
过表的方法有讲究:不要默读,要遮住右列自己复述,卡壳的地方做个记号,第二遍只过记号。第二遍还卡,就回到那一节把对应的例题重做一次,尤其是多重度和顺序图协作图对比这两块,做题比看书有效得多。
再补一个自查动作:拿一张白纸,不看书把九种图按“静态/动态、结构/行为”两个维度画成一张二维表,再把四种关系画成一条从弱到强的线——依赖、关联、聚集、组合,泛化和实现单独挂在旁边。画得出来说明地图在脑子里;画不出来说明还是靠零散记忆在撑,考场上换个问法就会翻车。
我自己的血泪经验是:第一遍复习时觉得关系图和多重度最简单,直接跳过,结果模拟时连着三道选择全错,错因还不是不会,是读题时想当然。从那以后每次做结构图相关的题,我都强制走一遍“先定关系、再读数量、最后用代码反推”的三步,哪怕题目标着“简单”也不省。希望帮到你。
本文还有配套的精品资源,点击获取