name: use-case-2.0 description: “Ivar Jacobson的用例2.0方法。涵盖用例切片、轻量级文档、用户故事派生和价值驱动优先级排序。适用于敏捷团队的现代用例建模方法。” allowed-tools: 读取, 写入, 全局, 搜索, 任务
用例2.0
一种现代的、轻量级的用例建模方法,集成了敏捷实践,同时保留了结构化需求的优点。
何时使用此技能
关键词: 用例, 用例2.0, Ivar Jacobson, 用例切片, 叙事, 基本流, 替代流, 异常, 参与者, 目标, 场景, 前置条件, 后置条件, 触发器, 从用例派生用户故事
在以下情况使用此技能:
- 从用户角度建模系统行为
- 从用例派生用户故事
- 使用用例切片规划发布
- 文档化具有多路径的复杂交互
- 理解参与者目标和系统响应
- 从叙事创建可测试的需求
什么是用例2.0?
用例2.0将经典用例现代化以适应敏捷环境,同时保留其在以下方面的优势:
- 全面捕获功能需求
- 理解系统边界和参与者
- 识别场景中的所有路径(快乐路径 + 替代路径 + 异常路径)
- 创建可追溯、可测试的规范
关键原则
| 原则 | 描述 |
|---|---|
| 基于切片 | 用例以切片实现,而非一次性完成 |
| 轻量级 | 从简单开始,仅在需要时添加细节 |
| 故事兼容 | 用户故事可从用例切片派生 |
| 测试先行 | 每个切片在实现前可测试 |
| 价值驱动 | 切片按业务价值优先级排序 |
用例2.0生命周期
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 发现 │ → │ 切片 │ → │ 准备 │
│ 用例 │ │ 用例 │ │ 用例切片 │
│ │ │ │ │ │
└──────────────┘ └──────────────┘ └──────────────┘
│
┌──────────────┐ ┌──────┴───────┐
│ 检查 │ ← │ 分析 │
│ 与适应 │ │ 切片 │
└──────────────┘ └──────────────┘
阶段详情
use_case_lifecycle:
find:
purpose: "从目标和参与者识别用例"
activities:
- "识别参与者(主要、支持、幕后)"
- "捕获参与者目标"
- "命名用例(动词-名词)"
- "创建用例图"
output: "用例模型(图表 + 简要描述)"
slice:
purpose: "将用例分解为可实现的切片"
activities:
- "识别基本流(快乐路径)"
- "识别替代流"
- "识别异常流"
- "将流分组为切片"
output: "带优先级的切片用例"
prepare:
purpose: "为切片实现详细化"
activities:
- "为选定切片编写叙事"
- "定义测试用例"
- "识别特殊需求"
output: "准备就绪的开发切片"
analyze:
purpose: "验证切片是否可实现"
activities:
- "与利益相关者评审"
- "验证测试用例"
- "确认验收标准"
output: "已验证的切片"
inspect_adapt:
purpose: "学习与改进"
activities:
- "评审已实现的切片"
- "更新用例模型"
- "优化剩余切片"
output: "更新的待办事项"
用例元素
参与者类型
actor_types:
primary_actor:
definition: "其目标由用例满足的参与者"
examples:
- "下订单的客户"
- "管理用户的管理员"
notation: "连接到用例的简图"
supporting_actor:
definition: "向系统提供服务的参与者"
examples:
- "处理支付的支付网关"
- "发送通知的电子邮件服务"
notation: "连接到用例的简图(标签)"
offstage_actor:
definition: "有兴趣但不直接交互的参与者"
examples:
- "需要交易日志的审计员"
- "需要合规的监管机构"
notation: "在利益相关者部分列出"
用例简要
轻量级初始文档:
use_case_brief:
template:
id: "UC-{domain}-{number}"
name: "{动词} {名词}"
primary_actor: "{参与者名称}"
goal: "{参与者想要实现的目标}"
brief_description: "{1-2句话}"
example:
id: "UC-ORD-001"
name: "下订单"
primary_actor: "客户"
goal: "从目录购买产品"
brief_description: "客户选择产品,提供运输和支付信息,并提交订单进行处理。"
用例叙事
完整文档格式:
## 用例:{名称}
**ID:** UC-{XXX}-{NNN}
**版本:** {N.N}
### 概述
| 元素 | 描述 |
|---------|-------------|
| **主要参与者** | {参与者名称} |
| **目标** | {参与者想要实现的目标} |
| **范围** | {系统边界} |
| **级别** | {用户目标 / 子功能 / 摘要} |
| **触发器** | {启动用例的事件} |
### 利益相关者与利益
- **{利益相关者1}**: {利益/关注点}
- **{利益相关者2}**: {利益/关注点}
### 前置条件
- {用例开始前必须为真的条件}
- {另一个前置条件}
### 成功保证(后置条件)
- {成功完成后保证为真的条件}
- {另一个后置条件}
### 基本流(主要成功场景)
1. {参与者} {行动}
2. 系统 {响应}
3. {参与者} {行动}
4. 系统 {响应}
5. ...
6. 系统 {指示成功的最终响应}
### 替代流
#### {替代名称}(在第{N}步)
**条件:** {此替代适用的情况}
{N}a. {替代行动}
{N}b. 系统 {替代响应}
{N}c. 返回第{M}步 / 用例结束
#### {另一个替代}(在第{N}步)
...
### 异常流
#### {异常名称}(在第{N}步)
**条件:** {此异常发生的情况}
{N}a. 系统 {错误检测}
{N}b. 系统 {错误处理}
{N}c. 用例以失败结束 / 返回第{M}步
### 特殊需求
- {影响此用例的非功能性需求}
- {性能、安全、可用性需求}
### 技术与数据变体
- {步骤N}: {技术或数据格式的变体}
### 相关信息
- **频率:** {此用例发生的频率}
- **相关用例:** {链接到包含/扩展的用例}
- **业务规则:** {BR-xxx, BR-yyy}
用例切片
什么是切片?
use_case_slice:
definition: "用例的子集,提供价值且独立可测试"
characteristics:
- "实现部分用例流"
- "可在一个迭代中开发"
- "有清晰的验收标准"
- "提供增量价值"
slice_types:
basic_flow_slice:
description: "仅快乐路径(最简单的实现)"
example: "下订单 - 现有客户的基本结账"
flow_variation_slice:
description: "基本流 + 一个替代"
example: "下订单 - 带新客户注册"
exception_slice:
description: "基本流 + 异常处理"
example: "下订单 - 支付被拒处理"
complete_slice:
description: "包含所有路径的完整用例"
example: "下订单 - 完整实现"
切片策略
slicing_strategies:
by_actor:
description: "不同参与者的不同切片"
example: "客户结账 vs. 管理员覆盖结账"
by_data_variation:
description: "不同的数据类型或量"
example: "单件订单 vs. 批量订单"
by_business_rule:
description: "应用的不同规则"
example: "标准定价 vs. 促销定价"
by_interface:
description: "不同的用户界面或集成点"
example: "网页结账 vs. API结账"
by_quality:
description: "不同的质量属性"
example: "基本验证 vs. 完整验证"
切片模板
use_case_slice:
id: "UC-{XXX}-{NNN}-S{NN}"
use_case: "UC-{XXX}-{NNN}"
name: "{用例名称} - {切片描述}"
scope:
flows_included:
- "基本流步骤1-6"
- "替代3a(访客结账)"
flows_excluded:
- "替代2a(保存的地址)"
- "异常5a(支付失败)"
value_statement: "{此切片为用户启用的功能}"
acceptance_criteria:
- given: "{前置条件}"
when: "{行动}"
then: "{预期结果}"
test_scenarios:
- "带有效数据的快乐路径"
- "无账户的访客结账"
estimate: "{故事点或理想天数}"
priority: "{价值/风险排名}"
用户故事派生
将用例切片转换为用户故事:
slice_to_story:
pattern: "每个切片成为一个或多个用户故事"
mapping:
use_case_name: "史诗名称"
slice: "用户故事"
acceptance_criteria: "验收标准"
test_scenarios: "测试用例"
example:
use_case: "下订单"
slices:
- slice: "基本结账"
story: |
作为客户
我想下订单,包含购物车中的商品
以便我能收到购买的产品
- slice: "访客结账"
story: |
作为访客
我想无需创建账户进行结账
以便我能快速完成购买
- slice: "支付重试"
story: |
作为客户
如果支付失败,我想重试支付
以便我能完成订单而无需重新开始
从用例的故事映射
用例模型 → 故事映射
───────────────── ─────────────────
UC: 下订单 史诗: 订单放置
├── 基本流 → ├── 基本结账
├── 替代: 访客结账 → ├── 访客结账
├── 替代: 保存地址 → ├── 地址管理
├── 替代: 礼品包装 → ├── 礼品选项
├── 异常: 支付失败 → ├── 支付错误处理
└── 异常: 缺货 → └── 库存处理
用例图
UML符号
┌─────────────────────────────────────────────────────────────────┐
│ 订单管理系统 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ╭──────────────╮ ╭─────────────────╮ │ │
│ │ │ 下订单 │───────│ 处理支付 │ │ │
│ │ ╰──────────────╯ ╰─────────────────╯ │ │
│ │ │ │ │ │
│ │ │ «include» │ «include» │ │
│ │ ▼ ▼ │ │
│ │ ╭──────────────╮ ╭─────────────────╮ │ │
│ │ │ 选择商品 │ │ 验证卡片 │ │ │
│ │ ╰──────────────╯ ╰─────────────────╯ │ │
│ │ │ │
│ │ ╭──────────────╮ │ │
│ │ │ 取消订单 │ │ │
│ │ ╰──────────────╯ │ │
│ │ ▲ │ │
│ │ │ «extend» │ │
│ │ │ [在取消窗口内] │ │
│ │ ╭──────────────╮ │ │
│ │ │ 查看订单 │ │ │
│ │ ╰──────────────╯ │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
○ ○
/|\ ────────── 下订单 /|\ ────────── 处理支付
/ \ / \
客户 支付网关
关系
use_case_relationships:
include:
notation: "«include»"
meaning: "基础用例始终包含此行为"
example: "下订单 «include» 处理支付"
arrow: "从基础到包含的虚线箭头"
extend:
notation: "«extend»"
meaning: "扩展用例可能在此条件下添加行为"
example: "查看订单 «extend» 取消订单 [在窗口内]"
arrow: "从扩展到基础的虚线箭头"
generalization:
notation: "三角形箭头"
meaning: "子用例继承父用例"
example: "用信用卡支付继承自进行支付"
.NET/C#实现
用例模型
// 用例2.0的领域模型
namespace Requirements.UseCases;
public record UseCase
{
public required string Id { get; init; }
public required string Name { get; init; }
public required Actor PrimaryActor { get; init; }
public required string Goal { get; init; }
public required UseCaseLevel Level { get; init; }
public string? Trigger { get; init; }
public string? Scope { get; init; }
public List<Stakeholder> Stakeholders { get; init; } = [];
public List<string> Preconditions { get; init; } = [];
public List<string> Postconditions { get; init; } = [];
public List<FlowStep> BasicFlow { get; init; } = [];
public List<AlternativeFlow> AlternativeFlows { get; init; } = [];
public List<ExceptionFlow> ExceptionFlows { get; init; } = [];
public List<string> SpecialRequirements { get; init; } = [];
public List<UseCaseSlice> Slices { get; init; } = [];
}
public enum UseCaseLevel
{
Summary, // 高层次业务流程
UserGoal, // 主要级别 - 用户实现目标
Subfunction // 支持功能
}
public record Actor(
string Name,
ActorType Type,
string? Description = null
);
public enum ActorType
{
Primary,
Supporting,
Offstage
}
public record FlowStep(
int StepNumber,
string ActorOrSystem,
string Action
);
public record AlternativeFlow(
string Name,
int BranchAtStep,
string Condition,
List<FlowStep> Steps,
FlowReturn Return
);
public record ExceptionFlow(
string Name,
int OccursAtStep,
string Condition,
List<FlowStep> Steps,
bool EndsInFailure
);
public record FlowReturn(
FlowReturnType Type,
int? ReturnToStep = null
);
public enum FlowReturnType
{
ReturnToBasicFlow,
EndUseCase,
EndInFailure
}
用例切片模型
public record UseCaseSlice
{
public required string Id { get; init; }
public required string UseCaseId { get; init; }
public required string Name { get; init; }
public required string ValueStatement { get; init; }
public List<string> IncludedFlows { get; init; } = [];
public List<string> ExcludedFlows { get; init; } = [];
public List<AcceptanceCriterion> AcceptanceCriteria { get; init; } = [];
public List<string> TestScenarios { get; init; } = [];
public int? StoryPoints { get; init; }
public SlicePriority Priority { get; init; }
public SliceStatus Status { get; init; }
}
public record AcceptanceCriterion(
string Given,
string When,
string Then
);
public enum SlicePriority
{
MustHave,
ShouldHave,
CouldHave,
WontHave
}
public enum SliceStatus
{
Identified,
Prepared,
Analyzed,
Implementing,
Done
}
切片到用户故事转换器
public class SliceToStoryConverter
{
public UserStory Convert(UseCaseSlice slice, UseCase useCase)
{
return new UserStory
{
Id = $"US-{slice.Id}",
Title = slice.Name,
Narrative = GenerateNarrative(slice, useCase),
AcceptanceCriteria = slice.AcceptanceCriteria
.Select(ac => $"Given {ac.Given}, When {ac.When}, Then {ac.Then}")
.ToList(),
Epic = useCase.Name,
StoryPoints = slice.StoryPoints,
Priority = MapPriority(slice.Priority)
};
}
private string GenerateNarrative(UseCaseSlice slice, UseCase useCase)
{
return $"""
As a {useCase.PrimaryActor.Name}
I want to {ExtractAction(slice, useCase)}
So that {useCase.Goal}
""";
}
private string ExtractAction(UseCaseSlice slice, UseCase useCase)
{
// 从包含流中提取主要行动
var mainFlow = slice.IncludedFlows.FirstOrDefault() ?? useCase.Name.ToLowerInvariant();
return mainFlow.Replace("Basic flow", useCase.Name.ToLowerInvariant());
}
private UserStoryPriority MapPriority(SlicePriority priority) =>
priority switch
{
SlicePriority.MustHave => UserStoryPriority.Critical,
SlicePriority.ShouldHave => UserStoryPriority.High,
SlicePriority.CouldHave => UserStoryPriority.Medium,
SlicePriority.WontHave => UserStoryPriority.Low,
_ => UserStoryPriority.Medium
};
}
public record UserStory
{
public required string Id { get; init; }
public required string Title { get; init; }
public required string Narrative { get; init; }
public List<string> AcceptanceCriteria { get; init; } = [];
public string? Epic { get; init; }
public int? StoryPoints { get; init; }
public UserStoryPriority Priority { get; init; }
}
public enum UserStoryPriority
{
Critical,
High,
Medium,
Low
}
最佳实践
编写良好用例
naming:
pattern: "动词 + 名词"
good_examples:
- "下订单"
- "注册客户"
- "生成报告"
bad_examples:
- "订单" # 无动词
- "客户注册系统" # 系统,而非目标
- "处理点击" # 过于低级
flow_writing:
guidelines:
- "用主动语态编写"
- "参与者或系统开始每一步"
- "每步一个可观察行动"
- "顺序编号步骤"
- "保持步骤在相同抽象级别"
good_steps:
- "1. 客户输入运输地址"
- "2. 系统验证地址格式"
- "3. 系统计算运输选项"
- "4. 客户选择运输方法"
bad_steps:
- "1. 点击提交按钮" # 过于详细
- "2. 发生某些事" # 过于模糊
- "3. 系统处理" # 无结果
level_selection:
user_goal: "主要级别 - 最常用"
summary: "用于业务流程概览"
subfunction: "用于共享功能(包含目标)"
切片指南
slice_sizing:
ideal: "每个切片1-5个故事点"
too_big: "无法在一个迭代中完成"
too_small: "未提供增量价值"
prioritization:
value_first: "基本流切片优先于替代流"
risk_reduction: "早期处理风险切片以学习"
dependency_aware: "先决条件在前,依赖在后"
coverage:
minimal_viable: "基本流切片 = 最小可行产品"
enhanced: "添加高价值替代流"
complete: "包含所有流,包括异常"
与其他技能的集成
上游
- 利益相关者模拟 - 识别参与者和目标
- 访谈进行 - 引出用例细节
- 差距分析 - 发现缺失用例
下游
- 用户故事映射 - 从切片派生故事
- 优先级排序方法 - 为切片排序优先级
- 业务规则分析 - 从流中提取规则
相关技能
- EARS编写(规范驱动开发) - 转换为EARS格式
- Gherkin编写(规范驱动开发) - 转换为Gherkin场景
输出格式
用例目录
use_case_catalog:
project: "{项目名称}"
version: "1.0"
last_updated: "{ISO-8601}"
actors:
- name: "客户"
type: "primary"
description: "购买产品的最终用户"
- name: "支付网关"
type: "supporting"
description: "外部支付处理器"
use_cases:
- id: "UC-ORD-001"
name: "下订单"
actor: "客户"
goal: "从目录购买产品"
level: "UserGoal"
slices:
- id: "UC-ORD-001-S01"
name: "基本结账"
status: "完成"
priority: "必须拥有"
- id: "UC-ORD-001-S02"
name: "访客结账"
status: "实现中"
priority: "应该拥有"
coverage:
total_use_cases: 12
total_slices: 34
slices_done: 18
slices_remaining: 16
参考
如需额外指导:
版本历史
- v1.0.0 (2025-12-26): 初始发布 - 用例2.0技能
最后更新: 2025-12-26