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

189 lines
6.9 KiB
Markdown

---
name: design-an-interface
description: "Backend Agent uses this skill to explore multiple API interface design options. Based on 'Design It Twice' principle, generate multiple distinct designs, compare, and select the best option. Trigger: API design phase (Stage 4), called by be-api-design skill."
---
# /design-an-interface — Interface Design Exploration
Backend Agent uses this skill to explore API interface design options.
Based on "Design It Twice" principle from "A Philosophy of Software Design": The first idea is usually not the best. Generate multiple distinct designs, then compare and choose.
## Responsibilities
1. Generate 2-3 distinct interface design options for module requirements
2. Each option uses different design constraints
3. Compare pros and cons of options
4. Assist in selecting or synthesizing the best option
## Input
- Module description (functional requirements from PRD)
- User stories and usage scenarios
## Output
- Multiple interface design options (including interface signatures, usage examples, pros/cons analysis)
- Option comparison and recommendations
## Flow
```
Collect requirements
Generate 2-3 design options (parallel sub-agents)
Present each option
Compare options (interface simplicity, generality, implementation efficiency, depth)
Synthesize best option or select most suitable
```
### Step Details
**1. Collect Requirements**
Before designing, understand:
- [ ] What problem does this module solve?
- [ ] Who are the callers? (other modules, external users, tests)
- [ ] What are the key operations?
- [ ] What are the constraints? (performance, compatibility, existing patterns)
- [ ] What should be hidden internally? What should be exposed externally?
Ask: "What does this module need to do? Who will use it?"
**2. Generate Design Options (Parallel Sub-Agents)**
Generate 3+ distinct options simultaneously. Each option must follow different constraints:
```
Option A: Minimize method count — target 1-3 methods
Option B: Maximize flexibility — support multiple use cases
Option C: Optimize for most common operations
Option D (optional): Reference specific paradigm or framework design
```
Each option should include:
1. Interface signature (types/methods)
2. Usage examples (how callers actually use it)
3. What complexity this design hides
4. Trade-offs of this option
**3. Present Options**
Present each option one by one, including:
- Interface signature: types, methods, params
- Usage examples: how callers actually use it
- Hidden complexity: small interface hiding large implementation (good) vs large interface with thin implementation (bad)
Allow user to fully absorb each option before comparison.
**4. Compare Options**
Compare across dimensions:
- **Interface simplicity**: Few methods, simple parameters → Easier to learn and use correctly
- **Generality vs Specificity**: Flexibility vs focus, where are the trade-offs
- **Implementation efficiency**: Does interface shape allow efficient internal implementation?
- **Depth**: Small interface hiding large complexity (deep module, good) vs large interface with thin implementation (shallow module, bad)
- **Ease of correct usage vs ease of misuse**
Discuss trade-offs in text, not just tables. Emphasize where options diverge most.
**5. Synthesize Best Option**
The best design often combines insights from multiple options. Ask:
- "Which option fits your primary use case best?"
- "Are there elements from other options worth incorporating?"
## Evaluation Criteria
From "A Philosophy of Software Design":
**Interface simplicity**: Few methods, simple parameters = Easier to learn and use correctly.
**Generality**: Can handle future use cases without modification. But avoid over-generalization.
**Implementation efficiency**: Does interface shape allow efficient implementation? Or does it force awkward internal implementation?
**Depth**: Small interface hiding large complexity = deep module (good). Large interface with thin implementation = shallow module (avoid).
```
Deep module (good):
┌─────────────────────┐
│ Small Interface │ ← Few methods, simple parameters
├─────────────────────┤
│ │
│ │
│ Deep Implementation│ ← Complex logic hidden inside
│ │
│ │
└─────────────────────┘
Shallow module (avoid):
┌─────────────────────────────────┐
│ Large Interface │ ← Many methods, complex parameters
├─────────────────────────────────┤
│ Thin Implementation │ ← Just a pass-through
└─────────────────────────────────┘
```
## Anti-Patterns
- Don't let sub-agents generate similar designs — force distinct ones
- Don't skip comparison — value comes from contrast
- Don't implement at this stage — this is pure interface design
- Don't evaluate options based on implementation effort — only look at interface quality
## Golang Interface Design Examples
```go
// Option A: Minimize method count
type UserRepository interface {
GetByID(ctx context.Context, id string) (*domain.User, error)
Save(ctx context.Context, user *domain.User) error
}
// Pros: Simple, easy to mock
// Cons: Save handles both Create and Update, depends on whether it exists
// Option B: Separate read/write
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
}
// Pros: CQRS friendly, separated concerns
// Cons: More methods, but each method has clearer semantics
// Option C: Optimize for common operations
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)
}
// Pros: Directly maps to business operations, most intuitive
// Cons: Need to add method for each new operation, less flexible
```
## Integration with be-api-design
This skill is automatically called by `be-api-design` at step 3. API design flow:
```
be-api-design step 1: Read PRD
be-api-design step 2: Identify resources and operations
→ design-an-interface: Explore 2-3 API design options
be-api-design step 4: Select option, define OpenAPI spec
```
## Related Skills
- **Prerequisite**: `write-a-prd` (PRD complete)
- **Follow-up**: `be-api-design` (API spec definition)