opencode-workflow/design-idea/translate/skills/design-an-interface/SKILL.md

189 lines
6.3 KiB
Markdown
Raw Normal View History

2026-04-08 23:53:15 +00:00
---
name: design-an-interface
description: "Backend Agent 使用此技能探索多種 API 介面設計方案。根據「Design It Twice」原則產生多種截然不同的設計比較後選擇最佳方案。觸發時機API 設計階段Stage 4由 be-api-design 技能呼叫。"
---
# /design-an-interface — 介面設計探索
Backend Agent 使用此技能探索 API 介面設計方案。
基於 "A Philosophy of Software Design" 的 "Design It Twice" 原則:第一個想法通常不是最好的。產生多種截然不同的設計,然後比較選擇。
## 職責
1. 針對模組需求,產生 2-3 種截然不同的介面設計方案
2. 每種方案使用不同的設計約束
3. 比較方案的優劣
4. 協助選擇或合成最佳方案
## 輸入
- 模組描述(來自 PRD 的功能性需求)
- 使用者故事和操作場景
## 輸出
- 多種介面設計方案(含介面簽名、使用範例、優劣分析)
- 方案比較和建議
## 流程
```
收集需求
產生 2-3 種設計方案(平行子代理)
呈現各方案
比較方案(介面簡潔性、通用性、實作效率、深度)
合成最佳方案或選擇最適方案
```
### 步驟說明
**1. 收集需求**
在設計之前,先了解:
- [ ] 這個模組解決什麼問題?
- [ ] 誰是呼叫者?(其他模組、外部使用者、測試)
- [ ] 關鍵操作有哪些?
- [ ] 有什麼限制?(效能、相容性、現有模式)
- [ ] 什麼應該隱藏在內部?什麼應該暴露在外?
提問:「這個模組需要做什麼?誰會使用它?」
**2. 產生設計方案(平行子代理)**
同時產生 3+ 種截然不同的方案。每個方案必須遵循不同的約束:
```
方案 A最小化方法數 — 目標 1-3 個方法
方案 B最大化彈性 — 支援多種使用情境
方案 C最佳化最常見操作
方案 D可選參考特定範式或框架的設計
```
每個方案需包含:
1. 介面簽名types / methods
2. 使用範例(呼叫者如何使用)
3. 這個設計隱藏了什麼複雜度
4. 這個方案的取捨
**3. 呈現方案**
逐一展示每個方案,包含:
- 介面簽名types, methods, params
- 使用範例:呼叫者如何實際使用
- 隱藏的複雜度小介面隱藏大量實作vs 大介面薄實作(差)
讓使用者充分吸收每個方案後再進行比較。
**4. 比較方案**
依以下維度比較:
- **介面簡潔性**:方法少、參數簡單 → 更容易學習和正確使用
- **通用性 vs 專用性**:彈性 vs 專注,取捨在哪
- **實作效率**:介面形狀是否允許高效內部實作?
- **深度**小介面隱藏大量複雜度深模組vs 大介面薄實作(淺模組,差)
- **正確使用的容易度 vs 誤用的容易度**
用文字討論取捨,不要只用表格。強調方案分歧最大的地方。
**5. 合成最佳方案**
最佳設計往往結合多個方案的洞見。詢問:
- 「哪個方案最適合你的主要使用情境?」
- 「其他方案有沒有值得納入的元素?」
## 評估標準
來自 "A Philosophy of Software Design"
**介面簡潔性**:方法少、參數簡單 = 更容易學習和正確使用。
**通用性**:能否處理未來的使用情境而不需要修改。但要避免過度通用。
**實作效率**:介面形狀是否允許高效實作?還是迫使內部實作變得彆扭?
**深度**:小介面隱藏大量複雜度 = 深模組(好)。大介面薄實作 = 淺模組(避免)。
```
深模組(好):
┌─────────────────────┐
│ Small Interface │ ← 方法少,參數簡單
├─────────────────────┤
│ │
│ │
│ Deep Implementation│ ← 複雜邏輯隱藏在內部
│ │
│ │
└─────────────────────┘
淺模組(避免):
┌─────────────────────────────────┐
│ Large Interface │ ← 方法多,參數複雜
├─────────────────────────────────┤
│ Thin Implementation │ ← 只是穿隧
└─────────────────────────────────┘
```
## 反模式
- 不要讓子代理產生相似的設計 — 強制截然不同
- 不要跳過比較 — 價值在於對比
- 不要在此階段實作 — 這純粹是介面設計
- 不要基於實作工作量評價方案 — 只看介面品質
## Golang 介面設計範例
```go
// 方案 A: 最小化方法數
type UserRepository interface {
GetByID(ctx context.Context, id string) (*domain.User, error)
Save(ctx context.Context, user *domain.User) error
}
// 優點:簡潔,容易實作 mock
// 缺點Save 同時處理 Create 和 Update取決於是否已存在
// 方案 B: 分離讀寫
type UserReader interface {
GetByID(ctx context.Context, id string) (*domain.User, error)
List(ctx context.Context, page, limit int) ([]*domain.User, error)
}
type UserWriter interface {
Create(ctx context.Context, user *domain.User) error
Update(ctx context.Context, user *domain.User) error
Delete(ctx context.Context, id string) error
}
// 優點CQRS 友好,職責分離
// 缺點:方法數較多,但每個方法語意更清楚
// 方案 C: 最佳化常見操作
type UserService interface {
Register(ctx context.Context, email, password, name string) (*domain.User, error)
Authenticate(ctx context.Context, email, password string) (*domain.User, error)
GetProfile(ctx context.Context, id string) (*domain.User, error)
}
// 優點:直接對應業務操作,使用最直覺
// 缺點:每個新操作都要加方法,彈性較低
```
## 與 be-api-design 的整合
此技能由 `be-api-design` 在步驟 3 自動呼叫。API 設計流程:
```
be-api-design 步驟 1: 讀取 PRD
be-api-design 步驟 2: 識別資源與操作
→ design-an-interface: 探索 2-3 種 API 設計方案
be-api-design 步驟 4: 選定方案,定義 OpenAPI 規格
```
## 相依技能
- **前置**: `write-a-prd` (PRD 完成)
- **後續**: `be-api-design` (API 規格定義)