| name | applying-design-patterns |
| description | Applies GoF and DDD design patterns in TypeScript: Factory, Repository, Strategy, Adapter, Decorator, Facade, Observer, Command, Specification. Use when picking the right structure for a feature or refactoring duplicated logic. |
Applying Design Patterns
When to use
- Picking the right structure for a new feature
- Refactoring duplicated logic
- Need pluggable algorithms or interchangeable implementations
Core rules
- Use patterns by name: Factory, Repository, Strategy, Adapter, Decorator, Facade, Observer, Command, Specification
- Patterns serve the business, not the other way around
- Prefer composition over inheritance
- All pattern implementations must be OOP classes with explicit typing
Reference shape (TypeScript)
Factory Pattern
export class UserFactory {
static createRegular(id: string, email: string): User {
return User.create(id, Email.create(email), ['user']);
}
static createAdmin(id: string, email: string): User {
return User.create(id, Email.create(email), ['user', 'admin']);
}
}
Strategy Pattern
export interface PricingStrategy { calculate(base: number): number; }
export class DiscountPricing implements PricingStrategy {
constructor(private discount: number) {}
calculate(base: number): number { return base - this.discount; }
}
Repository Pattern
export interface OrderRepository {
findById(id: string): Promise<Order | null>;
save(order: Order): Promise<Order>;
}
Examples — Do
class CreateOrderCommand {
constructor(public readonly userId: string, public readonly items: OrderItem[]) {}
}
class CreateOrderHandler {
async handle(cmd: CreateOrderCommand): Promise<Result<Order, AppError>> { ... }
}
Examples — Don't
class UserBuilder { setName(n: string) { this.name = n; return this; } }
Checklist
See reference/pattern-examples.md for full patterns.