名称: 用例编写 描述: 使用 Use Case 2.0 方法论捕获功能需求并记录参与者-系统交互 允许工具: 读取, 全局搜索, 查找, 写入, 编辑
用例编写技能
使用 Use Case 2.0 方法论捕获功能需求并文档化参与者-系统交互。
强制要求: 文档优先方法
在编写用例之前:
- 调用
docs-management技能获取需求模式 - 通过 MCP 服务器验证 Use Case 2.0 方法论
- 所有指导基于 Ivar Jacobson 的 Use Case 2.0
Use Case 2.0 概述
Use Case 2.0 是一种可扩展的敏捷实践,用于捕获需求:
| 方面 | 描述 |
|---|---|
| 轻量级 | 从最小开始,根据需要详细化 |
| 可扩展 | 适用于小型和大型系统 |
| 敏捷友好 | 支持迭代开发 |
| 可追溯 | 链接到测试和实现 |
用例结构
用例规范模板
# 用例: 提交订单
**ID:** UC-ORD-001
**版本:** 1.2
**作者:** 系统分析师
## 简要描述
客户提交草稿订单进行处理,触发库存预留和支付处理。
## 参与者
| 参与者 | 类型 | 描述 |
|-------|------|-------------|
| 客户 | 主要 | 下订单的人 |
| 支付网关 | 支持 | 外部支付处理器 |
| 库存系统 | 支持 | 管理产品库存 |
## 前置条件
1. 客户已认证
2. 订单处于草稿状态
3. 订单包含至少一个商品
4. 客户有有效的支付方式存档
## 后置条件
### 成功后置条件
1. 订单状态更改为已提交
2. 所有商品库存已预留
3. 支付授权已获取
4. 确认通知发送给客户
### 失败后置条件
1. 订单保持草稿状态
2. 无库存变更
3. 客户收到失败原因通知
## 基本流程(幸福路径)
| 步骤 | 参与者 | 系统 |
|------|-------|--------|
| 1 | 客户选择“提交订单” | |
| 2 | | 系统验证订单内容 |
| 3 | | 系统检查库存可用性 |
| 4 | | 系统预留所有商品的库存 |
| 5 | | 系统计算订单总计(小计 + 税 + 运费) |
| 6 | | 系统从支付网关请求支付授权 |
| 7 | | 支付网关授权支付 |
| 8 | | 系统更新订单状态为已提交 |
| 9 | | 系统向客户发送确认邮件 |
| 10 | | 系统显示订单确认页面 |
## 替代流程
### AF1: 部分库存可用
**触发:** 步骤 3 - 一些商品不可用
| 步骤 | 参与者 | 系统 |
|------|-------|--------|
| 3a | | 系统识别不可用商品 |
| 3b | | 系统向客户显示不可用商品 |
| 3c | 客户选择: 移除商品 / 等待补货 / 取消 | |
| 3d | | 如果移除: 系统更新订单,返回步骤 3 |
| 3e | | 如果等待: 系统创建备货单,继续到步骤 4 |
| 3f | | 如果取消: 结束用例(订单未变) |
### AF2: 支付被拒绝
**触发:** 步骤 7 - 支付授权失败
| 步骤 | 参与者 | 系统 |
|------|-------|--------|
| 7a | | 支付网关返回拒绝原因 |
| 7b | | 系统释放预留的库存 |
| 7c | | 系统向客户显示支付错误 |
| 7d | 客户更新支付方式 | |
| 7e | | 系统返回步骤 6 |
| 7f | | 3 次失败尝试后: 结束用例(失败) |
### AF3: 客户取消
**触发:** 任何步骤 - 客户点击取消
| 步骤 | 参与者 | 系统 |
|------|-------|--------|
| *a | 客户选择“取消” | |
| *b | | 系统释放任何预留的库存 |
| *c | | 系统返回到订单详情页面 |
| *d | | 结束用例(订单保持草稿) |
## 异常流程
### EF1: 系统不可用
**触发:** 任何步骤 - 系统组件无法访问
| 步骤 | 系统 |
|------|--------|
| 1 | 系统检测到组件不可用 |
| 2 | 系统记录带有相关 ID 的错误 |
| 3 | 系统显示“服务暂时不可用”消息 |
| 4 | 系统建议 5 分钟后重试 |
| 5 | 结束用例 |
### EF2: 会话超时
**触发:** 任何步骤 - 客户会话过期
| 步骤 | 系统 |
|------|--------|
| 1 | 系统检测到过期会话 |
| 2 | 系统保存订单状态(如果可能) |
| 3 | 系统重定向到登录页面 |
| 4 | 重新登录后: 恢复到最后完成的步骤 |
## 业务规则
| ID | 规则 |
|----|------|
| BR-001 | 订单必须包含至少一个商品 |
| BR-002 | 所有商品必须有正数量 |
| BR-003 | 支付授权必须在状态变更前获取 |
| BR-004 | 库存必须原子预留(全或无) |
| BR-005 | 确认邮件必须在 30 秒内发送 |
## 非功能性需求
| ID | 类别 | 需求 |
|----|----------|-------------|
| NFR-001 | 性能 | 订单提交在 3 秒内完成(p95) |
| NFR-002 | 可用性 | 服务可用时间 99.9% |
| NFR-003 | 可扩展性 | 支持 1000 个并发提交 |
| NFR-004 | 安全性 | 所有支付数据在传输中加密 |
## UI 线框图/原型
- 订单摘要页面: [链接到原型]
- 支付确认: [链接到原型]
- 错误状态: [链接到原型]
## 相关用例
| 用例 | 关系 |
|----------|--------------|
| UC-ORD-002: 取消订单 | 扩展 |
| UC-PAY-001: 处理支付 | 包含 |
| UC-INV-001: 预留库存 | 包含 |
| UC-NOT-001: 发送通知 | 包含 |
## 测试场景
| 场景 ID | 描述 | 覆盖步骤 |
|-------------|-------------|---------------|
| TS-001 | 幸福路径提交 | 基本流程 1-10 |
| TS-002 | 部分库存 | AF1 |
| TS-003 | 支付拒绝和重试 | AF2 |
| TS-004 | 客户取消 | AF3 |
| TS-005 | 会话超时恢复 | EF2 |
## 修订历史
| 版本 | 日期 | 作者 | 变更 |
|---------|------|--------|---------|
| 1.0 | 2025-01-01 | J. Smith | 初始版本 |
| 1.1 | 2025-01-10 | J. Smith | 添加 AF2 支付重试逻辑 |
| 1.2 | 2025-01-15 | M. Jones | 添加 NFR-003 可扩展性需求 |
用例图
PlantUML 语法
@startuml
left to right direction
skinparam packageStyle rectangle
actor Customer
actor "Payment Gateway" as PG <<system>>
actor "Inventory System" as INV <<system>>
rectangle "订单管理系统" {
usecase "浏览产品" as UC1
usecase "添加到购物车" as UC2
usecase "查看购物车" as UC3
usecase "提交订单" as UC4
usecase "跟踪订单" as UC5
usecase "取消订单" as UC6
usecase "请求退款" as UC7
usecase "处理支付" as UC_PAY
usecase "预留库存" as UC_INV
usecase "发送通知" as UC_NOT
}
Customer --> UC1
Customer --> UC2
Customer --> UC3
Customer --> UC4
Customer --> UC5
Customer --> UC6
Customer --> UC7
UC4 ..> UC_PAY : <<include>>
UC4 ..> UC_INV : <<include>>
UC4 ..> UC_NOT : <<include>>
UC6 ..> UC4 : <<extend>>
{order submitted}
UC7 ..> UC5 : <<extend>>
{order delivered}
UC_PAY --> PG
UC_INV --> INV
@enduml
Mermaid 语法
graph LR
subgraph Actors
C[Customer]
PG[Payment Gateway]
INV[Inventory System]
end
subgraph "订单管理系统"
UC1[浏览产品]
UC2[添加到购物车]
UC3[查看购物车]
UC4[提交订单]
UC5[跟踪订单]
UC6[取消订单]
UC_PAY[处理支付]
UC_INV[预留库存]
end
C --> UC1
C --> UC2
C --> UC3
C --> UC4
C --> UC5
C --> UC6
UC4 -.->|include| UC_PAY
UC4 -.->|include| UC_INV
UC6 -.->|extend| UC4
UC_PAY --> PG
UC_INV --> INV
用例切片
Use Case 2.0 引入切片用于增量实现:
切片定义
# 用例切片: 提交订单 - 基本流程
**用例:** UC-ORD-001: 提交订单
**切片 ID:** UC-ORD-001-S01
**优先级:** 高
**冲刺:** 冲刺 3
## 范围
此切片实现订单提交的基本幸福路径,无替代流程。
## 包含流程
- 基本流程: 步骤 1-10
## 排除流程(未来切片)
- AF1: 部分库存(切片 S02)
- AF2: 支付被拒绝(切片 S02)
- AF3: 客户取消(切片 S03)
## 验收标准
```gherkin
功能: 提交订单 - 基本流程
场景: 成功提交有效订单
假设 我以客户身份登录
并且 我有一个包含 2 个商品的草稿订单
并且 所有商品有库存
并且 我有有效的支付方式
当 我点击“提交订单”
那么 我的订单状态应为“已提交”
并且 我应收到确认邮件
并且 我应看到确认页面
## 用户故事
| 故事 ID | 描述 | 点数 |
|----------|-------------|--------|
| US-301 | 作为客户,我想提交我的订单 | 5 |
| US-302 | 作为客户,我想在提交后获得确认 | 2 |
| US-303 | 作为系统,我需要预留库存 | 3 |
参与者目录
# 参与者目录
## 人类参与者
### 客户
**描述:** 浏览产品并下订单的最终用户
**目标:**
- 快速找到产品
- 高效完成购买
- 跟踪订单状态
- 在需要时获得支持
**特征:**
- 可能有不同的技术水平
- 期望响应迅速、直观的界面
- 重视订单状态透明度
### 管理员
**描述:** 管理平台配置的系统操作员
**目标:**
- 配置系统设置
- 监控系统健康
- 管理用户账户
- 生成报告
## 系统参与者
### 支付网关
**类型:** 外部系统
**描述:** 第三方支付处理器(Stripe, PayPal)
**接口:** REST API
**交互:**
- 授权支付
- 捕获支付
- 处理退款
### 库存系统
**类型:** 外部系统
**描述:** 仓库管理系统
**接口:** 消息队列(RabbitMQ)
**交互:**
- 检查可用性
- 预留库存
- 释放库存
- 确认发货
### 通知服务
**类型:** 内部系统
**描述:** 邮件和短信通知分发器
**接口:** 内部 API
**交互:**
- 发送确认邮件
- 发送发货更新
- 发送促销消息
C# 实现映射
// 用例到应用服务映射
public interface ISubmitOrderUseCase
{
/// <summary>
/// 执行 UC-ORD-001: 提交订单
/// </summary>
/// <remarks>
/// 基本流程: 步骤 1-10
/// 前置条件: 客户已认证,订单草稿,有商品
/// 后置条件: 订单已提交,库存已预留,支付已授权
/// </remarks>
Task<Result<OrderConfirmation>> ExecuteAsync(
SubmitOrderCommand command,
CancellationToken ct = default);
}
public sealed class SubmitOrderUseCase : ISubmitOrderUseCase
{
private readonly IOrderRepository _orders;
private readonly IInventoryService _inventory;
private readonly IPaymentGateway _payments;
private readonly INotificationService _notifications;
private readonly ILogger<SubmitOrderUseCase> _logger;
public SubmitOrderUseCase(
IOrderRepository orders,
IInventoryService inventory,
IPaymentGateway payments,
INotificationService notifications,
ILogger<SubmitOrderUseCase> logger)
{
_orders = orders;
_inventory = inventory;
_payments = payments;
_notifications = notifications;
_logger = logger;
}
public async Task<Result<OrderConfirmation>> ExecuteAsync(
SubmitOrderCommand command,
CancellationToken ct = default)
{
// 步骤 2: 验证订单内容
var order = await _orders.GetByIdAsync(command.OrderId, ct);
if (order is null)
return Result.Failure<OrderConfirmation>("订单未找到");
var validationResult = ValidateOrder(order);
if (validationResult.IsFailure)
return validationResult.ToResult<OrderConfirmation>();
// 步骤 3-4: 检查并预留库存
var inventoryResult = await _inventory.ReserveAsync(order.Items, ct);
if (inventoryResult.IsFailure)
return HandlePartialInventory(order, inventoryResult); // AF1
try
{
// 步骤 5-7: 处理支付
var paymentResult = await _payments.AuthorizeAsync(
order.CustomerId,
order.CalculateTotal(),
ct);
if (paymentResult.IsFailure)
{
await _inventory.ReleaseAsync(order.Items, ct); // AF2 步骤 7b
return HandlePaymentFailure(order, paymentResult);
}
// 步骤 8: 更新订单状态
order.Submit(paymentResult.Value.AuthorizationCode);
await _orders.UpdateAsync(order, ct);
// 步骤 9: 发送确认
await _notifications.SendOrderConfirmationAsync(order, ct);
// 步骤 10: 返回确认
return Result.Success(new OrderConfirmation(
order.Id,
order.Status,
order.CalculateTotal(),
DateTimeOffset.UtcNow));
}
catch (Exception ex)
{
// EF1: 系统不可用
_logger.LogError(ex, "订单提交失败 {OrderId}", order.Id);
await _inventory.ReleaseAsync(order.Items, ct);
return Result.Failure<OrderConfirmation>("服务暂时不可用");
}
}
private Result ValidateOrder(Order order)
{
// BR-001: 订单必须包含至少一个商品
if (!order.Items.Any())
return Result.Failure("订单必须包含至少一个商品");
// BR-002: 所有商品必须有正数量
if (order.Items.Any(i => i.Quantity <= 0))
return Result.Failure("所有商品必须有正数量");
// 前置条件: 订单草稿状态
if (order.Status != OrderStatus.Draft)
return Result.Failure("只有草稿订单可以提交");
return Result.Success();
}
private Result<OrderConfirmation> HandlePartialInventory(
Order order,
Result inventoryResult)
{
// AF1: 部分库存处理
// 完整实现中,将返回结构化错误与不可用商品
return Result.Failure<OrderConfirmation>(
$"一些商品不可用: {inventoryResult.Error}");
}
private Result<OrderConfirmation> HandlePaymentFailure(
Order order,
Result paymentResult)
{
// AF2: 支付被拒绝
return Result.Failure<OrderConfirmation>(
$"支付被拒绝: {paymentResult.Error}");
}
}
// 命令对象
public sealed record SubmitOrderCommand(
Guid OrderId,
Guid CustomerId);
// 响应对象
public sealed record OrderConfirmation(
Guid OrderId,
OrderStatus Status,
Money Total,
DateTimeOffset SubmittedAt);
关系类型
| 关系 | 符号 | 描述 |
|---|---|---|
| 包含 | <<include>> |
基础用例总是包含目标用例 |
| 扩展 | <<extend>> |
扩展用例可选地扩展基础 |
| 泛化 | 箭头 | 特化用例从一般继承 |
何时使用每种
包含: 提取通用行为(例如,认证)
- “提交订单”包含“认证用户”
- 总是发生,非可选
扩展: 可选/条件行为
- “取消订单”扩展“查看订单”(仅当状态允许时)
- “应用优惠券”扩展“结账”(仅当客户有优惠券时)
泛化: 特化版本
- “使用信用卡支付”特化“处理支付”
- “使用 PayPal 支付”特化“处理支付”
工作流程
编写用例时:
- 识别参与者: 谁与系统交互?
- 定义系统边界: 范围内外是什么?
- 列出用例: 参与者实现什么目标?
- 写简要描述: 一句话摘要
- 详细化流程: 先基本流程,然后替代
- 定义前置/后置条件: 状态变化
- 识别业务规则: 约束和政策
- 创建切片: 优先增量交付
- 映射到测试: 验收标准和场景
最佳实践
- 用户中心: 从参与者视角编写
- 目标导向: 每个用例实现一个目标
- 技术无关: 描述什么,而非如何
- 可测试: 清晰的验收标准
- 增量: 使用切片进行敏捷交付
- 可追溯: 链接到需求和测试
参考资料
详细指导:
最后更新: 2025-12-26