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

6.3 KiB
Raw Blame History

name description
design-an-interface 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 介面設計範例

// 方案 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 規格定義)