需求分析概述与面向对象建模
需求分析的根本任务
需求分析承担着两项核心任务:建立分析模型与创建解决方案。这一阶段是连接用户需求与软件实现的关键桥梁。
建立分析模型
模型是对事物的抽象,帮助我们在创建系统之前更好地理解它。建模的核心方法包括:
- 抽象(Abstraction):聚焦重要信息,忽略次要内容,将认知保持在适当层次
- 分解(Decomposition):「分而治之」,将复杂问题拆解为更易管理的子问题
- 投影(Projection):从多个视角观察同一系统,即多视点方法
三种模型的层次关系
- 业务模型:使用问题域概念,非形式化,便于用户理解但不够精确
- 分析模型:介于两者之间,半形式化,既能被用户理解又具备一定严谨性
- 计算模型:使用软件构建单位,形式化,精确但用户难以理解
需求分析阶段主要建立的是分析模型——它采用计算模型的组元形式,但以业务模型的方式表现。
创建解决方案
解决方案的创建是一个创造性过程,受到多重因素影响:
| 外因 | 内因 |
|---|---|
| 问题背景 | 技术背景 |
| 需求本身 | 知识背景 |
| 可用技术与方法 | 经验与习惯 |
最终的解决方案往往来源于这些因素交织产生的创造性灵感。
需求分析的活动
需求分析包含三个主要活动**:需求细化**、确定优先级和需求协商。
需求细化
需求细化的目标是将用户视角的需求转化为技术视角的系统需求:
- 明确用户需求的隐含因素
- 将业务语言转化为技术语言
- 将高层次非功能需求分解为具体约束
- 发现并补充细节需求
每条细化后的需求应记录以下属性:
| 属性 | 说明 |
|---|---|
| 标识符(ID) | 唯一标识 |
| 源头(Source) | 可追溯的需求来源 |
| 理由(Rational) | 需求被提出的目的 |
| 优先级(Priority) | 重要程度 |
| 成本(Cost) | 预估实现代价 |
| 风险(Risk) | 实现过程中的潜在风险 |
| 可变性(Volatility) | 未来变更的可能性 |
确定需求优先级
常用的优先级确定方法:
累计投票法:涉众对需求进行投票,票数反映优先级。
区域划分法:基于「重要性」与「紧急性」两个维度划分四象限:
---
config:
quadrantChart:
chartWidth: 600
chartHeight: 500
titlePadding: 15
titleFontSize: 22
quadrantPadding: 8
quadrantTextTopPadding: 10
quadrantLabelFontSize: 14
quadrantInternalBorderStrokeWidth: 1
quadrantExternalBorderStrokeWidth: 2
xAxisLabelPadding: 8
xAxisLabelFontSize: 14
xAxisPosition: "bottom"
yAxisLabelPadding: 8
yAxisLabelFontSize: 14
yAxisPosition: "left"
pointTextPadding: 6
pointLabelFontSize: 12
pointRadius: 6
themeVariables:
quadrant1Fill: "#FF6B6B"
quadrant2Fill: "#4ECDC4"
quadrant3Fill: "#FFD166"
quadrant4Fill: "#06D6A0"
quadrant1TextFill: "#FFFFFF"
quadrant2TextFill: "#FFFFFF"
quadrant3TextFill: "#333333"
quadrant4TextFill: "#FFFFFF"
quadrantPointFill: "#1A1A2E"
quadrantPointTextFill: "#1A1A2E"
quadrantXAxisTextFill: "#333333"
quadrantYAxisTextFill: "#333333"
quadrantInternalBorderStrokeFill: "#E0E0E0"
quadrantExternalBorderStrokeFill: "#333333"
quadrantTitleFill: "#1A1A2E"
---
quadrantChart
title 需求优先级矩阵
x-axis "低紧急性" --> "高紧急性"
y-axis "低重要性" --> "高重要性"
quadrant-1 "高优先级(紧急且重要)"
quadrant-2 "中优先级(重要不紧急)"
quadrant-3 "低优先级(不重要不紧急)"
quadrant-4 "中优先级(紧急不重要)"
"关键缺陷修复": [0.85, 0.85]
"核心功能迭代": [0.25, 0.80]
"界面美化": [0.20, 0.25]
"临时支持请求": [0.75, 0.30]
"安全漏洞": [0.90, 0.90]
"技术债务": [0.15, 0.60]
"文档更新": [0.30, 0.40]
Top-N 法:选取优先级最高的 N 个需求,N 的取值受实现代价总和约束。
数据量化法:通过公式计算优先级:
用户故事地图:基于延迟成本进行判断——延迟成本相同时短任务优先,工作量相同时高延迟成本优先。
需求协商
当需求存在冲突时,需要通过协商达成一致:
- 明确冲突的因素,避免情绪化
- 明确冲突的解决空间
- 确定最佳解决方案,实现多方共赢
需求分析技术的演进
---
config:
theme: base
themeVariables:
# 1950's 传统分析 - 复古棕色
cScale0: "#8B7355"
cScaleLabel0: "#FFFFFF"
# 1970's 结构化分析 - 科技蓝色
cScale1: "#2E5A88"
cScaleLabel1: "#FFFFFF"
# 1980's 信息工程 - 数据绿色
cScale2: "#4A7C59"
cScaleLabel2: "#FFFFFF"
# 1990's 面向对象 - 现代紫色
cScale3: "#6A4C93"
cScaleLabel3: "#FFFFFF"
# 时间线样式
timelineFontSize: "16px"
timelineColor: "#333333"
timelineLineColor: "#CCCCCC"
---
timeline
title 系统分析方法演进历史
section 1950's
传统分析
: 依赖个体才智
: 无结构、不可重复
: 风格:非正式、个人化
section 1970's
结构化分析
: 数据流图(DFD)
: 实体关系图(ERD)
: 状态转移图
: 风格:流程化、结构化
section 1980's
信息工程
: 以数据为中心
: ERD 为核心
: 风格:数据驱动、集成化
section 1990's
面向对象分析
: UML 统一建模语言
: 类图、用例图、交互图
: 风格:对象化、标准化
面向对象分析
核心思想
面向对象思想源于对现实世界复杂系统的观察:
- 复杂系统由简单部分组合而成,组合过程具有层次性
- 每个最小部分独立负责一系列相关任务
- 组合内部各部分的关系比内外部关系更紧密
- 各部分通过一致的接口进行组合
映射到软件世界:
- 计算实体:对象
- 层次关系:继承、关联、聚合、组合
- 组合接口:对象暴露的公共接口
UML 建模体系
UML 为面向对象分析提供了完整的建模工具集:
| 模型类型 | 主要图形 | 用途 |
|---|---|---|
| 用例模型 | 用例图 | 描述系统功能与参与者 |
| 对象模型 | 类图/领域模型 | 描述系统静态结构 |
| 行为模型 | 顺序图、状态图、活动图 | 描述系统动态行为 |
对象模型
对象的基本概念
对象是在应用中具有明确角色的独立可确认实体,包含三个要素:
- 标识:唯一标识自己
- 状态:对象的属性及其取值
- 行为:对象响应消息或状态变化时采取的行动
常见的对象来源:
- 与系统交互的外部实体(人、设备、其他系统)
- 问题域中的事物(报表、信号)
- 系统上下文中的事件(控制行为、资源变化)
- 用户扮演的角色(管理员、普通用户)
- 相关的组织单位(部门、团队)
- 问题发生的地点(车间、办公室)
不是对象的事物
- 无法界定的事物
- 纯粹的值(如单独的数字)
- 纯粹的行为(无状态支撑)
类与分类
类是共享相同属性和行为的对象集合,为所属对象提供:
- 接口(Interface):对外的统一协议
- 实现(Implementation):生成机制和行为模式
分类的两种驱动方式:
| 方式 | 理论基础 | 特点 |
|---|---|---|
| 数据驱动 | 经典分类理论 | 具有相同属性的对象归为一类 |
| 职责驱动 | 概念聚类 | 依据相似性而非完全相同性分类 |
关联
关联表示类之间的语义联系,是对对象实例间潜在关系的描述。
关联的表示要素:
- 关联名称与方向
- 角色名
- 多重性(基数)
- 可见性
- 限定符
特殊的关联类型:
- 聚合:整体与部分的关系,部分可独立存在
- 组合:更强的整体-部分关系,部分不能独立存在
领域模型
领域模型是需求分析阶段的核心产物,其特点:
- 类多为概念类,代表现实世界事物
- 关联通常不标记方向和可见性
- 只显示重要属性,不约束类型
- 不显式标记方法
1 | ┌─────────────┐ ┌─────────────┐ |
classDiagram
class Sale {
date
time
}
class SalesLineItem {
quantity
}
class Payment {
amount
}
class Item
Sale "1" -- "*" SalesLineItem : contains
Sale "0..1" -- "1" Payment : paid by
SalesLineItem "*" -- "1" Item : records
领域模型建模步骤
-
发现候选对象
- 概念类分类列表法:按预定义分类(人、地点、事物、事件等)查找
- 名词分析法:从文本中提取名词和名词短语
-
判定结果类
- 既有状态又有行为 → 独立对象
- 只有状态无行为 → 考虑作为属性
- 只有行为无状态 → 可能存在需求遗漏
-
建立关联:保证协作所需的可见性,适度使用问题域关联
-
添加重要属性:协作的条件、输入、结果或过程记录
行为模型:顺序图
顺序图基础
顺序图以一组对象为中心,描述特定上下文中对象间的消息交换,通常对应单个用例的典型场景。
基本元素:
- 对象:带生命线的矩形
- 消息:对象间的交互(同步、异步、返回)
- 激活态:对象执行操作的时间段
- 创建/销毁:对象的生命周期事件
系统顺序图
将整个系统视为黑箱,强调外部参与者与系统的交互:
sequenceDiagram
participant 收银员
participant 系统
收银员->>系统: 开始新的销售处理
loop 还有下一项
收银员->>系统: 输入物品项
系统-->>收银员: 物品描述、价格、总价
end
收银员->>系统: 结束销售处理
系统-->>收银员: 总价
组合片段
用于表达复杂的控制逻辑:
| 片段类型 | 用途 |
|---|---|
opt |
可选执行(单一条件) |
alt |
多分支选择 |
loop |
循环执行 |
break |
中断序列 |
par |
并行执行 |
ref |
引用其他图 |
建模步骤
- 确定上下文环境
- 找出参与交互的对象
- 建立交互图框架(对象平行排列,添加生命线)
- 添加消息,描述交互行为和顺序
- 为分支和异常场景添加组合片段
行为模型:状态图
状态机理论
状态机理论的核心观点:
- 系统总是处于某一状态中,且同一时刻只能处于一种状态
- 没有外部事件触发时,系统保持当前状态
- 有效触发事件发生时,系统从一种状态转移到另一种状态
有限状态机的形式化定义
有限自动机是一个五元组 :
- :有限状态集
- :有限输入字母表
- :转移函数
- :初始状态
- :接受状态集
状态图元素
- 状态:系统的稳定配置
- 转换:状态间的迁移
- 事件:触发转换的外部刺激
- 监护条件:转换发生的前提条件
- 行为:转换时执行的动作
高级特性:
- 组合状态:包含子状态的复合状态
- 并发状态:同时处于多个正交状态
- 历史状态:记忆上次离开时的子状态
建模步骤
- 确定状态主体(类、用例或整个系统)
- 识别所有状态,标记初始和结束状态
- 建立状态转换,明确触发事件和监护条件
- 补充详细信息(入口/出口动作、内部活动等)
通过状态图发现需求缺陷
- 无法进入或无法跳出的状态 → 行为缺失
- 转移路线不确定 → 监护条件数据缺失或行为需细化
- 应有的转移或状态未体现 → 需求内容需修正
对象约束语言 OCL
OCL(Object Constraint Language)是一种无副作用的规约语言,用于丰富 UML 模型的语义。
OCL 的定位
- 以表达式方式定义对模型元素的约束
- 不修改任何模型元素的表述
- 是建模语言而非编程语言,注重简洁性和抽象性
主要应用
不变量(Invariant):类元需要始终保持为真的约束
1 | context Flight |
前置条件与后置条件:操作执行前后必须满足的约束
1 | context LoyaltyAccount::burn(i: Integer) |
监护条件:状态转移发生的前提条件
[i > 0] -- 只有当 i > 0 时才进行转移 |
操作契约示例
1 | 操作:enterItem(ItemID, quantity) |
CRC 方法
CRC(Candidates, Responsibilities, Collaborators)是处理复杂系统时进行面向对象分析的有效手段。
CRC 卡结构
graph LR
subgraph "CRC 卡结构"
A["候选对象名称"] --> B["职责 Responsibilities"]
A --> C["协作者 Collaborators"]
B --> D["• 对象执行的行为<br/>• 对象维护的状态"]
C --> E["• 需要协作的对象"]
end
style A fill:#4a6fa5,stroke:#333,stroke-width:2px,color:#fff
style B fill:#6d9eeb,stroke:#333,stroke-width:1px,color:#fff
style C fill:#6d9eeb,stroke:#333,stroke-width:1px,color:#fff
style D fill:#e6f2ff,stroke:#4a6fa5,stroke-width:1px
style E fill:#e6f2ff,stroke:#4a6fa5,stroke-width:1px
CRC 方法流程
flowchart LR
A[🎯 确定主题]
B[🔍 识别候选对象<br/>建立CRC卡]
C[📋 发现系统职责]
D[⚖️ 分配职责到对象]
E[🤝 建立对象协作关系]
F[✨ 细化CRC卡]
G[🚀 基于CRC卡的设计]
A -->|开始分析| B
B -->|识别对象| C
C -->|明确职责| D
D -->|职责分配| E
E -->|建立关系| F
F -->|迭代优化| G
style A fill:#ff6b6b,stroke:#333,stroke-width:2px,color:#fff
style B fill:#4ecdc4,stroke:#333,stroke-width:2px,color:#fff
style C fill:#45b7d1,stroke:#333,stroke-width:2px,color:#fff
style D fill:#96ceb4,stroke:#333,stroke-width:2px,color:#fff
style E fill:#feca57,stroke:#333,stroke-width:2px,color:#fff
style F fill:#ff9ff3,stroke:#333,stroke-width:2px,color:#fff
style G fill:#54a0ff,stroke:#333,stroke-width:2px,color:#fff
%% 添加连接线样式
linkStyle default stroke:#5d6d7e,stroke-width:2px,fill:none
CRC 卡的优势在于其简洁灵活,可以随时移动、修改或丢弃,特别适合在复杂系统中进行对象发现和设计思想挖掘。
本章要点总结
面向对象分析以 UML 为基础,综合运用多种分析技术:
| 模型 | 核心技术 | 主要作用 |
|---|---|---|
| 对象模型 | 领域模型/概念类图 | 发现数据方面的需求缺陷 |
| 用例模型 | 用例图、用例描述 | 捕获功能需求 |
| 行为模型 | 顺序图、状态图 | 发现行为和状态方面的缺陷 |
| 约束规约 | OCL | 精确定义业务规则 |
成功的面向对象分析不仅需要掌握这些技术,更需要理解如何综合运用它们来发现和弥补需求中的缺陷与不足。