FDD Best Practices: Learning from Anti-Patterns
During a recent code review of our shadow portfolio feature, we discovered a concerning pattern where FDD documentation was artificially inflated by duplicating TypeScript type definitions. This experience provides valuable lessons about what makes FDD documentation effective - and what doesn't.
🚫 Bad FDD Practices
1. Type Definition Duplication
# Bad Example
## Technical Implementation
interface ShadowPosition {
id: string;
symbol: string;
direction: 'LONG' | 'SHORT';
// ... 50 more lines of type definitions
}
Why it's bad:
- Creates multiple sources of truth
- Requires synchronization when types change
- Makes documentation harder to maintain
- Bloats the FDD with information available elsewhere
2. Code Block Overuse
# Bad Example
## Queue Components
```typescript
interface QueueJob {
id: string;
type: JobType;
// ... entire interface definition
}
```
Why it's bad:
- Duplicates information from source files
- Makes FDD unnecessarily long
- Distracts from architectural decisions
3. Implementation Details Overload
# Bad Example
## Job Management
Detailed implementation showing how to create jobs with specific parameter types and validation rules...
// ... pages of implementation details that belong in code
Why it's bad:
- Mixes documentation with implementation
- Creates maintenance burden
- Makes it hard to find important information
✅ Good FDD Practices
1. Type References
# Good Example
## Core Components
The system uses `ShadowPosition` entity (defined in `shadow-portfolio.types.ts`)
to track trading positions with the following key aspects:
- Position direction and status tracking
- Entry/exit price management
- Performance metrics collection
Why it's good:
- References instead of duplicates
- Focuses on component purposes
- Easy to maintain
2. Architectural Decisions
# Good Example
## Queue Design Decisions
1. Using Bull.js for job processing because:
- Reliable Redis-based persistence
- Built-in retry mechanisms
- Support for job priorities
- Excellent TypeScript integration
Why it's good:
- Documents why decisions were made
- Provides context for future developers
- Focuses on architecture, not implementation
3. Component Relationships
# Good Example
## System Components
- Position Manager → handles position lifecycle
- Queue Worker → processes position updates
- Artifact Generator → creates position documentation
Each component is loosely coupled through well-defined interfaces
(see `shadow-portfolio.types.ts` for interface definitions)
Why it's good:
- Shows system structure
- Explains component relationships
- References types without duplicating them
Best Practices for FDD Writing
1. Single Source of Truth
- Keep type definitions in
.tsfiles - Reference types in FDD instead of duplicating
- Link to source files for implementation details
2. Focus on Architecture
- Document why decisions were made
- Explain system structure
- Highlight component relationships
- Describe integration points
3. Progressive Documentation
- Start with high-level overview
- Provide clear component purposes
- Add implementation notes where necessary
- Keep technical details in code
4. Maintainability First
- Make documentation easy to update
- Avoid duplicating information
- Use references to source files
- Keep FDDs focused and concise
Conclusion
FDD documentation should serve as a guide for understanding and maintaining a feature, not as a repository of duplicated code. By focusing on architectural decisions, component relationships, and system design while referencing (rather than duplicating) implementation details, we create more valuable and maintainable documentation.
Remember:
- Good FDDs explain the "why" and "how" of system architecture
- Code explains the "what" of implementation
- Keep them separate and reference when needed
By following these guidelines, we create documentation that:
- Is easier to maintain
- Provides more value to developers
- Remains accurate over time
- Actually gets read and used
Let's make our FDDs work for the team, not for line count.
Tags
#SoftwareEngineering #Documentation #BestPractices #FDD #TypeScript #Architecture
