Skip to main content

FDD Best Practices: Learning from Anti-Patterns

· 3 min read
Max Kaido
Architect

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 .ts files
  • 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:

  1. Is easier to maintain
  2. Provides more value to developers
  3. Remains accurate over time
  4. 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