Back to skills
SkillHub ClubDesign ProductFull StackData / AIDesigner

design-patterns

Analyze codebase for GoF design patterns - detection, suggestions, evaluation with stack-aware adaptations

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
1,951
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
C67.6

Install command

npx @skill-hub/cli install florianbruniaux-claude-code-ultimate-guide-design-patterns

Repository

FlorianBruniaux/claude-code-ultimate-guide

Skill path: examples/skills/design-patterns

Analyze codebase for GoF design patterns - detection, suggestions, evaluation with stack-aware adaptations

Open repository

Best for

Primary workflow: Design Product.

Technical facets: Full Stack, Data / AI, Designer.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: FlorianBruniaux.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install design-patterns into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/FlorianBruniaux/claude-code-ultimate-guide before adding design-patterns to shared team environments
  • Use design-patterns for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: design-patterns
description: Analyze codebase for GoF design patterns - detection, suggestions, evaluation with stack-aware adaptations
allowed-tools: Read, Grep, Glob, mcp__grepai__grepai_search
context: fork
agent: specialist
---

# Design Patterns Analyzer Skill

**Purpose**: Detect, suggest, and evaluate Gang of Four (GoF) design patterns in TypeScript/JavaScript codebases with stack-aware adaptations.

## Core Capabilities

1. **Stack Detection**: Identify primary framework/library (React, Angular, NestJS, Vue, Express, RxJS, Redux, ORMs)
2. **Pattern Detection**: Find existing implementations of 23 GoF patterns
3. **Smart Suggestions**: Recommend patterns to fix code smells, using stack-native idioms when available
4. **Quality Evaluation**: Assess pattern implementation quality against best practices

## Operating Modes

### Mode 1: Detection

**Trigger**: User requests pattern detection or analysis
**Output**: JSON report of patterns found with confidence scores and stack context

**Workflow**:
```
1. Stack Detection (package.json, tsconfig.json, framework files)
2. Pattern Search (Glob for candidates → Grep for signatures → Read for validation)
3. Classification (native to stack vs custom implementations)
4. Confidence Scoring (0.0-1.0 based on detection rules)
5. JSON Report Generation
```

**Example invocation**:
```
/design-patterns detect src/
/design-patterns analyze --format=json
```

### Mode 2: Suggestion

**Trigger**: User requests pattern suggestions or refactoring advice
**Output**: Markdown report with prioritized suggestions and stack-adapted examples

**Workflow**:
```
1. Code Smell Detection (switch statements, long parameter lists, global state, etc.)
2. Pattern Matching (map smell → applicable patterns)
3. Stack Adaptation (prefer native framework patterns over custom implementations)
4. Priority Ranking (impact × feasibility)
5. Markdown Report with Code Examples
```

**Example invocation**:
```
/design-patterns suggest src/payment/
/design-patterns refactor --focus=creational
```

### Mode 3: Evaluation

**Trigger**: User requests pattern quality assessment
**Output**: JSON report with scores per evaluation criterion

**Workflow**:
```
1. Pattern Identification (which pattern is implemented)
2. Criteria Assessment (correctness, testability, SOLID compliance, documentation)
3. Issue Detection (common mistakes, anti-patterns)
4. Scoring (0-10 per criterion)
5. JSON Report with Recommendations
```

**Example invocation**:
```
/design-patterns evaluate src/services/singleton.ts
/design-patterns quality --pattern=observer
```

## Methodology

### Phase 1: Stack Detection

**Sources** (in priority order):
1. `package.json` → Check dependencies and devDependencies
2. Framework-specific files → `angular.json`, `next.config.*`, `nest-cli.json`, `vite.config.*`
3. `tsconfig.json` → Check compilerOptions, paths, lib
4. File extensions → `*.jsx`, `*.tsx`, `*.vue` presence

**Detection Rules** (from `signatures/stack-patterns.yaml`):
- React: `react` in deps + `*.jsx/*.tsx` files
- Angular: `@angular/core` + `angular.json`
- NestJS: `@nestjs/core` + `nest-cli.json`
- Vue: `vue` v3+ + `*.vue` files
- Express: `express` in deps + `app.use` patterns
- RxJS: `rxjs` in deps + Observable usage
- Redux/Zustand: `redux`/`zustand` in deps + store patterns
- Prisma/TypeORM: `prisma`/`typeorm` in deps + schema files

**Output**:
```json
{
  "stack_detected": {
    "primary": "react",
    "version": "18.2.0",
    "secondary": ["typescript", "zustand", "prisma"],
    "detection_sources": ["package.json", "tsconfig.json", "37 *.tsx files"],
    "confidence": 0.95
  }
}
```

### Phase 2: Pattern Detection

**Search Strategy**:
1. **Glob Phase**: Find candidate files by naming convention
   - `*Singleton*.ts`, `*Factory*.ts`, `*Strategy*.ts`, `*Observer*.ts`, etc.
   - `*Manager*.ts`, `*Builder*.ts`, `*Adapter*.ts`, `*Proxy*.ts`, etc.

2. **Grep Phase**: Search for pattern signatures (from `signatures/detection-rules.yaml`)
   - Primary signals: `private constructor`, `static getInstance()`, `subscribe()`, `createXxx()`, etc.
   - Secondary signals: Interface naming, delegation patterns, method signatures

3. **Read Phase**: Validate pattern structure
   - Parse class/interface definitions
   - Verify relationships (inheritance, composition, delegation)
   - Check for complete pattern implementation vs partial usage

**Confidence Scoring**:
- 0.9-1.0: All primary + secondary signals present, structure matches exactly
- 0.7-0.89: All primary signals + some secondary, minor deviations
- 0.5-0.69: Primary signals present, missing secondary validation
- 0.3-0.49: Naming convention matches, weak structural evidence
- 0.0-0.29: Insufficient evidence, likely false positive

**Classification**:
- `native`: Pattern implemented using stack-native features (React Context, Angular Services, NestJS Guards, etc.)
- `custom`: Manual TypeScript implementation
- `library`: Third-party library providing pattern (RxJS Subject, Redux Store, etc.)

### Phase 3: Code Smell Detection

**Target Smells** (from `signatures/code-smells.yaml`):
1. **Switch on Type** → Strategy/Factory pattern
2. **Long Parameter List (>4)** → Builder pattern
3. **Global State Access** → Singleton (or preferably DI)
4. **Duplicated Conditionals on State** → State pattern
5. **Scattered Notification Logic** → Observer pattern
6. **Complex Object Creation** → Factory/Abstract Factory
7. **Tight Coupling to Concrete Classes** → Adapter/Bridge
8. **Repetitive Interface Conversions** → Adapter pattern
9. **Deep Nesting for Feature Addition** → Decorator pattern
10. **Large Class with Many Responsibilities** → Facade pattern

**Detection Heuristics**:
- Grep for `switch (.*type)`, `switch (.*kind)`, `switch (.*mode)`
- Count function parameters: `function \w+\([^)]{60,}\)` (approximation for >4 params)
- Search for global access: `window\.`, `global\.`, `process\.env\.\w+` (not in config files)
- Find state conditionals: `if.*state.*===.*&&.*if.*state.*===`
- Find notification patterns: `forEach.*notify`, `map.*\.emit\(`

### Phase 4: Stack-Aware Suggestions

**Adaptation Logic** (from `signatures/stack-patterns.yaml`):

```
IF pattern_detected == "custom" AND stack_has_native_equivalent:
  SUGGEST: "Use stack-native pattern instead"
  PROVIDE: Side-by-side comparison (current vs recommended)

ELSE IF code_smell_detected AND pattern_missing:
  IF stack_provides_pattern:
    SUGGEST: Stack-native implementation with examples
  ELSE:
    SUGGEST: Custom TypeScript implementation with best practices

ELSE IF pattern_implemented_incorrectly:
  PROVIDE: Refactoring steps to fix anti-patterns
```

**Example Adaptations**:

| Pattern | Stack | Native Alternative | Recommendation |
|---------|-------|-------------------|----------------|
| Singleton | React | Context API + Provider | Use `createContext()` instead of `getInstance()` |
| Observer | Angular | RxJS Subject/BehaviorSubject | Use built-in Observables, not custom implementation |
| Decorator | NestJS | @Injectable() decorators + Interceptors | Use framework interceptors |
| Strategy | Vue 3 | Composition API composables | Use `ref()` + composables instead of classes |
| Chain of Responsibility | Express | Middleware (`app.use()`) | Use Express middleware chain |
| Command | Redux | Action creators + reducers | Use Redux actions, not custom command objects |

### Phase 5: Quality Evaluation

**Criteria** (from `checklists/pattern-evaluation.md`):
1. **Correctness (0-10)**: Does it match the canonical pattern structure?
2. **Testability (0-10)**: Can dependencies be mocked/stubbed easily?
3. **Single Responsibility (0-10)**: Does it do one thing only?
4. **Open/Closed Principle (0-10)**: Extensible without modification?
5. **Documentation (0-10)**: Clear intent, descriptive naming?

**Scoring Guidelines**:
- 9-10: Exemplary, reference-quality implementation
- 7-8: Good, minor improvements possible
- 5-6: Acceptable, notable issues to address
- 3-4: Problematic, significant refactoring needed
- 0-2: Incorrect or severely flawed

**Issue Detection**:
- Hard-coded dependencies (Singleton with new inside getInstance)
- God classes (too many responsibilities)
- Leaky abstractions (exposing internal structure)
- Missing error handling
- Poor naming (Strategy1, Strategy2 instead of descriptive names)

## Output Formats

### Detection Mode (JSON)

```json
{
  "metadata": {
    "scan_date": "2026-01-21T10:30:00Z",
    "scope": "src/",
    "files_scanned": 147,
    "execution_time_ms": 2341
  },
  "stack_detected": {
    "primary": "react",
    "version": "18.2.0",
    "secondary": ["typescript", "zustand", "prisma"],
    "detection_sources": ["package.json", "tsconfig.json", "37 *.tsx files"],
    "confidence": 0.95
  },
  "patterns_found": {
    "singleton": [
      {
        "file": "src/lib/api-client.ts",
        "lines": "5-28",
        "confidence": 0.85,
        "type": "custom",
        "signals": ["private constructor", "static getInstance", "private static instance"],
        "note": "Consider using React Context instead for better testability"
      }
    ],
    "observer": [
      {
        "file": "src/hooks/useAuth.ts",
        "lines": "12-45",
        "confidence": 0.92,
        "type": "native",
        "implementation": "React useState + useEffect",
        "note": "Correctly using React's built-in observer pattern"
      }
    ],
    "factory": [
      {
        "file": "src/services/notification-factory.ts",
        "lines": "8-67",
        "confidence": 0.78,
        "type": "custom",
        "signals": ["createNotification method", "type discrimination", "returns interface"]
      }
    ]
  },
  "summary": {
    "total_patterns": 7,
    "native_to_stack": 4,
    "custom_implementations": 3,
    "by_category": {
      "creational": 2,
      "structural": 3,
      "behavioral": 2
    },
    "by_confidence": {
      "high": 5,
      "medium": 2,
      "low": 0
    }
  },
  "recommendations": [
    "Consider replacing custom Singleton (api-client.ts) with React Context for better DI",
    "Review Factory pattern (notification-factory.ts) - could be simplified with strategy pattern"
  ]
}
```

### Suggestion Mode (Markdown)

```markdown
# Design Pattern Suggestions

**Scope**: `src/payment/`
**Stack**: React 18 + TypeScript + Stripe
**Date**: 2026-01-21

---

## High Priority

### 1. Strategy Pattern → `src/payment/processor.ts:45-89`

**Code Smell**: Switch statement on payment type (4 cases, 78 lines)

**Current Implementation** (lines 52-87):
```typescript
switch (paymentType) {
  case 'credit':
    // 20 lines of credit card logic
    break;
  case 'paypal':
    // 15 lines of PayPal logic
    break;
  case 'crypto':
    // 18 lines of crypto logic
    break;
  case 'bank':
    // 12 lines of bank transfer logic
    break;
}
```

**Recommended (React-adapted Strategy)**:
```typescript
// Define strategy interface
interface PaymentStrategy {
  process: (amount: number) => Promise<PaymentResult>;
}

// Custom hooks as strategies
const useCreditPayment = (): PaymentStrategy => ({
  process: async (amount) => { /* credit logic */ }
});

const usePaypalPayment = (): PaymentStrategy => ({
  process: async (amount) => { /* PayPal logic */ }
});

// Strategy selection hook
const usePaymentStrategy = (type: PaymentType): PaymentStrategy => {
  const strategies = {
    credit: useCreditPayment(),
    paypal: usePaypalPayment(),
    crypto: useCryptoPayment(),
    bank: useBankPayment(),
  };
  return strategies[type];
};

// Usage in component
const PaymentForm = ({ type }: Props) => {
  const strategy = usePaymentStrategy(type);
  const handlePay = () => strategy.process(amount);
  // ...
};
```

**Impact**:
- **Complexity**: Reduces cyclomatic complexity from 12 to 2
- **Extensibility**: New payment methods = new hook, no modification to existing code
- **Testability**: Each strategy hook can be tested in isolation
- **Effort**: ~2 hours (extract logic into hooks, add tests)

---

## Medium Priority

### 2. Observer Pattern → `src/cart/CartManager.ts:23-156`

**Code Smell**: Manual notification logic scattered across 8 methods

**Current**: Manual loops calling update functions
**Recommended**: Use Zustand store (already in dependencies)

```typescript
// Instead of custom observer:
import create from 'zustand';

interface CartStore {
  items: CartItem[];
  addItem: (item: CartItem) => void;
  removeItem: (id: string) => void;
  // Zustand automatically notifies subscribers
}

export const useCartStore = create<CartStore>((set) => ({
  items: [],
  addItem: (item) => set((state) => ({ items: [...state.items, item] })),
  removeItem: (id) => set((state) => ({ items: state.items.filter(i => i.id !== id) })),
}));

// Components auto-subscribe:
const CartDisplay = () => {
  const items = useCartStore((state) => state.items);
  // Re-renders automatically on cart changes
};
```

**Impact**:
- **LOC**: Reduces from 156 to ~25 lines
- **Stack-native**: Uses existing Zustand dependency
- **Testability**: Zustand stores are easily tested
- **Effort**: ~1.5 hours

---

## Summary

- **Total suggestions**: 4
- **High priority**: 2 (Strategy, Observer)
- **Medium priority**: 2 (Builder, Facade)
- **Estimated total effort**: ~6 hours
- **Primary benefits**: Reduced complexity, improved testability, stack-native idioms
```

### Evaluation Mode (JSON)

```json
{
  "file": "src/services/config-singleton.ts",
  "pattern": "singleton",
  "lines": "5-34",
  "scores": {
    "correctness": 8,
    "testability": 4,
    "single_responsibility": 9,
    "open_closed": 7,
    "documentation": 6,
    "overall": 6.8
  },
  "details": {
    "correctness": {
      "score": 8,
      "rationale": "Implements singleton structure correctly with private constructor and static getInstance",
      "issues": ["Missing thread-safety consideration (not critical in JS single-threaded context)"]
    },
    "testability": {
      "score": 4,
      "rationale": "Hard to mock or reset instance in tests",
      "issues": [
        "No reset method for test isolation",
        "Static instance makes dependency injection impossible",
        "Tests must run in specific order or share state"
      ],
      "suggestions": [
        "Add resetInstance() method for tests (with appropriate guards)",
        "Consider using dependency injection instead"
      ]
    },
    "single_responsibility": {
      "score": 9,
      "rationale": "Focuses solely on configuration management",
      "issues": []
    },
    "open_closed": {
      "score": 7,
      "rationale": "Configuration can be extended but requires modification for new sources",
      "suggestions": ["Consider strategy pattern for configuration sources"]
    },
    "documentation": {
      "score": 6,
      "rationale": "Has JSDoc but missing rationale for singleton choice",
      "suggestions": ["Document why singleton is chosen over DI", "Add usage examples"]
    }
  },
  "recommendations": [
    {
      "priority": "high",
      "suggestion": "Add test-friendly reset mechanism or refactor to use DI",
      "rationale": "Current implementation makes testing difficult"
    },
    {
      "priority": "medium",
      "suggestion": "Document singleton rationale in JSDoc",
      "rationale": "Team members should understand why global state is necessary here"
    }
  ]
}
```

## Constraints & Guidelines

### Read-Only Analysis
- **No modifications**: This skill only analyzes and suggests, never modifies code
- **No file creation**: Does not generate refactored code files
- **User decision**: All suggestions require explicit user approval before implementation

### Language Focus
- **Primary**: TypeScript (`.ts`, `.tsx`)
- **Secondary**: JavaScript (`.js`, `.jsx`)
- **Exclusions**: Other languages (Python, Java, C#) not supported

### Pattern Coverage
- **Creational (5)**: Singleton, Factory Method, Abstract Factory, Builder, Prototype
- **Structural (7)**: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy
- **Behavioral (11)**: Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor, Interpreter

### Performance Considerations
- **Large codebases (>500 files)**: Use `--scope` to limit scan to specific directories
- **Parallel search**: Grep searches run independently for each pattern
- **Caching**: Stack detection results cached per session to avoid redundant package.json reads

## Usage Examples

### Basic Detection
```bash
# Detect all patterns in src/
/design-patterns detect src/

# Detect only creational patterns
/design-patterns detect src/ --category=creational

# Focus on specific pattern
/design-patterns detect src/ --pattern=singleton
```

### Targeted Suggestions
```bash
# Get suggestions for payment module
/design-patterns suggest src/payment/

# Focus on specific smell
/design-patterns suggest src/ --smell=switch-on-type

# High priority only
/design-patterns suggest src/ --priority=high
```

### Quality Evaluation
```bash
# Evaluate specific file
/design-patterns evaluate src/services/api-client.ts

# Evaluate all singletons
/design-patterns evaluate src/ --pattern=singleton

# Full quality report
/design-patterns evaluate src/ --detailed
```

## Integration with Other Skills

This skill can be inherited by:
- `refactoring-specialist.md` → Provides pattern knowledge for refactoring
- `code-reviewer.md` → Adds pattern detection to review process
- `architecture-advisor.md` → Informs architectural decisions with pattern usage

## Reference Files

- `reference/patterns-index.yaml` → Machine-readable index of 23 patterns with metadata
- `reference/creational.md` → Creational patterns documentation
- `reference/structural.md` → Structural patterns documentation
- `reference/behavioral.md` → Behavioral patterns documentation
- `signatures/detection-rules.yaml` → Regex patterns and heuristics for detection
- `signatures/code-smells.yaml` → Mapping from code smells to applicable patterns
- `signatures/stack-patterns.yaml` → Stack detection rules and native pattern equivalents
- `checklists/pattern-evaluation.md` → Quality evaluation criteria and scoring guidelines

## Version

**Skill Version**: 1.0.0
**Pattern Coverage**: 23 GoF patterns
**Supported Stacks**: 8 (React, Angular, NestJS, Vue, Express, RxJS, Redux/Zustand, ORMs)
**Last Updated**: 2026-01-21


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### signatures/stack-patterns.yaml

```yaml
version: "1.0.0"
description: Stack detection rules and pattern adaptations for framework-native idioms

# Stack Detection Rules
stack_detection:
  sources:
    - file: "package.json"
      check: "dependencies + devDependencies"
      priority: 1
    - file: "tsconfig.json"
      check: "compilerOptions, paths, lib"
      priority: 2
    - files: ["angular.json", "next.config.*", "nest-cli.json", "vite.config.*", "nuxt.config.*"]
      check: "presence"
      priority: 1
    - pattern: "*.jsx, *.tsx, *.vue, *.svelte"
      check: "file extensions"
      priority: 3

  confidence_scoring:
    high: "Primary framework found in package.json + config file present"
    medium: "Framework in package.json OR config file present"
    low: "Only file extensions or indirect evidence"

# Supported Stacks
stacks:
  react:
    detection:
      package_json:
        required: ["react"]
        optional: ["react-dom", "next", "@types/react"]
      files:
        optional: ["next.config.js", "next.config.ts", "vite.config.ts"]
      extensions: [".jsx", ".tsx"]

    version_detection:
      hooks_era: ">=16.8.0"  # useState, useEffect introduced
      concurrent: ">=18.0.0"  # Concurrent features

    native_patterns:
      singleton:
        replacement: "Context API + Provider"
        example: |
          // Instead of Singleton
          const MyContext = createContext<ContextValue>(defaultValue);
          export const MyProvider = ({ children }) => (
            <MyContext.Provider value={value}>{children}</MyContext.Provider>
          );
        rationale: "Context provides dependency injection without global state"
        confidence: 0.95

      observer:
        replacement: "useState + useEffect"
        example: |
          const [value, setValue] = useState(initial);
          useEffect(() => {
            // React auto-notifies subscribers
          }, [value]);
        rationale: "React's reactivity system is built-in observer pattern"
        confidence: 0.98

      strategy:
        replacement: "Custom hooks"
        example: |
          const usePaymentStrategy = (type: PaymentType) => {
            const strategies = {
              credit: useCreditPayment(),
              paypal: usePaypalPayment(),
            };
            return strategies[type];
          };
        rationale: "Hooks encapsulate behavior and are composable"
        confidence: 0.90

      decorator:
        replacement: "Higher-Order Components (HOC)"
        example: |
          const withAuth = <P extends object>(Component: React.ComponentType<P>) => {
            return (props: P) => {
              const { user } = useAuth();
              if (!user) return <Redirect to="/login" />;
              return <Component {...props} />;
            };
          };
        rationale: "HOCs wrap components to add behavior"
        confidence: 0.85

      mediator:
        replacement: "Context API"
        example: |
          // Centralized state management
          const AppContext = createContext<AppState>(initialState);
          // Components communicate through context
        rationale: "Context mediates communication between components"
        confidence: 0.80

    recommendations:
      - "Prefer hooks over class-based patterns"
      - "Use Context for shared state, not Singleton"
      - "Leverage built-in reactivity instead of manual observer"
      - "Consider React Query/SWR for data fetching patterns"

  angular:
    detection:
      package_json:
        required: ["@angular/core"]
        optional: ["@angular/common", "@angular/platform-browser"]
      files:
        required: ["angular.json"]
      extensions: [".ts"]

    version_detection:
      standalone: ">=14.0.0"  # Standalone components
      signals: ">=16.0.0"     # Signals API

    native_patterns:
      singleton:
        replacement: "@Injectable() services"
        example: |
          @Injectable({ providedIn: 'root' })
          export class ConfigService {
            // Automatically singleton via DI
          }
        rationale: "Angular's DI container manages singleton lifecycle"
        confidence: 0.98

      observer:
        replacement: "RxJS Observables"
        example: |
          import { BehaviorSubject } from 'rxjs';
          private data$ = new BehaviorSubject<Data>(initial);
          getData() { return this.data$.asObservable(); }
        rationale: "RxJS is Angular's standard reactive programming library"
        confidence: 0.98

      decorator:
        replacement: "Directives and Pipes"
        example: |
          @Directive({ selector: '[appHighlight]' })
          export class HighlightDirective {
            // Adds behavior to DOM elements
          }
        rationale: "Angular decorators are first-class pattern"
        confidence: 0.95

      facade:
        replacement: "Service with injected dependencies"
        example: |
          @Injectable()
          export class UserFacade {
            constructor(
              private userService: UserService,
              private authService: AuthService,
              private profileService: ProfileService
            ) {}
          }
        rationale: "Services naturally encapsulate subsystems"
        confidence: 0.90

    recommendations:
      - "Use DI instead of manual singleton patterns"
      - "Leverage RxJS for all reactive patterns"
      - "Use Angular decorators (@Component, @Directive, @Pipe)"
      - "Services should be injected, not manually instantiated"

  nestjs:
    detection:
      package_json:
        required: ["@nestjs/core"]
        optional: ["@nestjs/common", "@nestjs/platform-express"]
      files:
        required: ["nest-cli.json"]
      extensions: [".ts"]

    native_patterns:
      singleton:
        replacement: "@Injectable() with default scope"
        example: |
          @Injectable() // Default scope is SINGLETON
          export class AppService {}
        rationale: "NestJS DI uses singleton scope by default"
        confidence: 0.98

      chain-of-responsibility:
        replacement: "Guards, Interceptors, Pipes, Middleware"
        example: |
          @Injectable()
          export class AuthGuard implements CanActivate {
            canActivate(context: ExecutionContext): boolean {
              // Guard chain
            }
          }
        rationale: "NestJS request pipeline is built-in chain pattern"
        confidence: 0.95

      decorator:
        replacement: "Interceptors"
        example: |
          @Injectable()
          export class LoggingInterceptor implements NestInterceptor {
            intercept(context: ExecutionContext, next: CallHandler) {
              // Wraps request handling
            }
          }
        rationale: "Interceptors add behavior to route handlers"
        confidence: 0.95

      facade:
        replacement: "Modules"
        example: |
          @Module({
            providers: [ServiceA, ServiceB],
            exports: [FacadeService]
          })
          export class FeatureModule {}
        rationale: "Modules encapsulate and export simplified interfaces"
        confidence: 0.85

      factory:
        replacement: "useFactory provider"
        example: |
          {
            provide: 'CONFIG',
            useFactory: (env: EnvService) => createConfig(env),
            inject: [EnvService]
          }
        rationale: "DI supports factory pattern natively"
        confidence: 0.90

    recommendations:
      - "Use built-in DI, never manual singleton"
      - "Leverage Guards/Interceptors/Pipes for cross-cutting concerns"
      - "Modules should export facades to subsystems"
      - "Use dynamic modules for configurable features"

  vue:
    detection:
      package_json:
        required: ["vue"]
        version: ">=3.0.0"
      files:
        optional: ["vite.config.ts", "nuxt.config.ts"]
      extensions: [".vue"]

    version_detection:
      composition_api: ">=3.0.0"  # Composition API default
      script_setup: ">=3.2.0"     # <script setup> sugar

    native_patterns:
      singleton:
        replacement: "Provide/Inject"
        example: |
          // Root component
          provide('config', reactive({ theme: 'dark' }));
          // Child component
          const config = inject('config');
        rationale: "Provide/Inject offers dependency injection"
        confidence: 0.90

      observer:
        replacement: "ref() and reactive()"
        example: |
          const count = ref(0);
          watch(count, (newVal) => {
            // Automatically notified on change
          });
        rationale: "Vue 3's reactivity is built-in observer"
        confidence: 0.98

      strategy:
        replacement: "Composables"
        example: |
          export function usePayment(type: PaymentType) {
            const strategies = {
              credit: useCreditPayment,
              paypal: usePaypalPayment,
            };
            return strategies[type]();
          }
        rationale: "Composables encapsulate reusable logic"
        confidence: 0.90

      mediator:
        replacement: "Pinia stores or global state"
        example: |
          export const useAppStore = defineStore('app', {
            state: () => ({ /* ... */ }),
            actions: { /* ... */ }
          });
        rationale: "Pinia centralizes state management"
        confidence: 0.85

    recommendations:
      - "Use Composition API for all new code"
      - "Leverage ref()/reactive() instead of manual observer"
      - "Use composables for strategy-like patterns"
      - "Pinia for global state, provide/inject for DI"

  express:
    detection:
      package_json:
        required: ["express"]
      extensions: [".js", ".ts"]

    native_patterns:
      chain-of-responsibility:
        replacement: "Middleware (app.use)"
        example: |
          app.use(authMiddleware);
          app.use(loggingMiddleware);
          app.use(errorMiddleware);
        rationale: "Express middleware is chain of responsibility"
        confidence: 0.98

      facade:
        replacement: "Router"
        example: |
          const userRouter = express.Router();
          userRouter.get('/', getUsers);
          userRouter.post('/', createUser);
          app.use('/users', userRouter);
        rationale: "Routers group related endpoints"
        confidence: 0.85

      template-method:
        replacement: "Route handlers with middleware"
        example: |
          app.get('/users',
            validateRequest,    // Step 1
            checkAuth,         // Step 2
            loadUser,          // Step 3
            (req, res) => {}   // Final step
          );
        rationale: "Middleware chain defines template"
        confidence: 0.75

    recommendations:
      - "Use middleware for cross-cutting concerns"
      - "Routers should group related functionality"
      - "Error handling middleware should be last"
      - "Avoid manual chain implementations"

  rxjs:
    detection:
      package_json:
        required: ["rxjs"]
      extensions: [".ts", ".js"]

    native_patterns:
      observer:
        replacement: "Subject, BehaviorSubject, ReplaySubject"
        example: |
          const subject = new BehaviorSubject<number>(0);
          subject.subscribe(value => console.log(value));
          subject.next(1); // Notifies subscribers
        rationale: "RxJS is the observer pattern library"
        confidence: 1.0

      strategy:
        replacement: "RxJS operators"
        example: |
          observable.pipe(
            map(x => x * 2),
            filter(x => x > 10),
            debounceTime(300)
          );
        rationale: "Operators are composable strategies"
        confidence: 0.90

      decorator:
        replacement: "pipe() operator"
        example: |
          source$.pipe(
            tap(x => console.log(x)),  // Add logging
            catchError(handleError)    // Add error handling
          );
        rationale: "pipe() chains operators that decorate behavior"
        confidence: 0.85

      chain-of-responsibility:
        replacement: "mergeMap, concatMap, switchMap"
        example: |
          requests$.pipe(
            mergeMap(req => processRequest(req)),
            catchError((err, caught) => caught) // Pass to next
          );
        rationale: "Operators chain processing steps"
        confidence: 0.75

    recommendations:
      - "Use Subject variants, not custom observer classes"
      - "Compose operators instead of manual logic"
      - "shareReplay() for caching/memoization"
      - "Avoid manual subscription management, use async pipe (Angular)"

  redux:
    detection:
      package_json:
        required_any: ["redux", "@reduxjs/toolkit", "zustand", "jotai", "recoil"]
      extensions: [".ts", ".js", ".tsx", ".jsx"]

    native_patterns:
      singleton:
        replacement: "Store"
        example: |
          // Redux
          const store = createStore(rootReducer);
          // Zustand
          export const useStore = create((set) => ({ /* ... */ }));
        rationale: "Store is managed singleton"
        confidence: 0.98

      command:
        replacement: "Actions and Action Creators"
        example: |
          // Redux action
          const incrementAction = { type: 'INCREMENT', payload: 1 };
          // Redux Toolkit
          const increment = createAction<number>('counter/increment');
        rationale: "Actions encapsulate state changes"
        confidence: 0.95

      observer:
        replacement: "Store subscriptions"
        example: |
          // Redux
          store.subscribe(() => console.log(store.getState()));
          // Zustand (React)
          const count = useStore(state => state.count);
        rationale: "Store notifies subscribers on state change"
        confidence: 0.95

      state:
        replacement: "Reducers"
        example: |
          const reducer = (state, action) => {
            switch (action.type) {
              case 'INCREMENT': return { count: state.count + 1 };
              // Different states handled by action type
            }
          };
        rationale: "Reducers implement state-dependent behavior"
        confidence: 0.85

      memento:
        replacement: "Time-travel debugging / Redux DevTools"
        example: |
          // Redux DevTools captures state snapshots
          // Can jump to any previous state
        rationale: "Store history enables memento pattern"
        confidence: 0.80

    recommendations:
      - "Use Redux Toolkit for modern Redux (reduces boilerplate)"
      - "Consider Zustand for simpler state management"
      - "Actions should be serializable (for time-travel)"
      - "Selectors should use reselect for memoization"

  orm:
    detection:
      package_json:
        required_any: ["prisma", "@prisma/client", "typeorm", "@mikro-orm/core", "sequelize"]
      files:
        optional: ["prisma/schema.prisma", "ormconfig.json"]
      extensions: [".ts"]

    native_patterns:
      repository:
        replacement: "Prisma Client / TypeORM Repository"
        example: |
          // Prisma
          const users = await prisma.user.findMany();
          // TypeORM
          const userRepo = dataSource.getRepository(User);
          const users = await userRepo.find();
        rationale: "ORMs provide repository pattern out-of-box"
        confidence: 0.95

      facade:
        replacement: "ORM Client"
        example: |
          // Prisma facades complex SQL
          await prisma.user.create({
            data: { name: 'Alice', posts: { create: [{ title: 'Hello' }] } }
          });
        rationale: "ORM simplifies database operations"
        confidence: 0.90

      builder:
        replacement: "Query Builder"
        example: |
          // Prisma
          prisma.user.findMany({ where: { age: { gte: 18 } }, orderBy: { name: 'asc' } });
          // TypeORM Query Builder
          userRepo.createQueryBuilder('user')
            .where('user.age >= :age', { age: 18 })
            .orderBy('user.name', 'ASC')
            .getMany();
        rationale: "Fluent interface for complex queries"
        confidence: 0.90

      unit-of-work:
        replacement: "Transactions"
        example: |
          await prisma.$transaction([
            prisma.user.create({ data: userData }),
            prisma.post.create({ data: postData })
          ]);
        rationale: "Transactions implement unit of work"
        confidence: 0.85

      lazy-loading:
        replacement: "Include/relations"
        example: |
          const user = await prisma.user.findUnique({
            where: { id: 1 },
            include: { posts: true } // Explicit eager loading
          });
        rationale: "ORMs control loading strategy"
        confidence: 0.80

    recommendations:
      - "Use ORM repositories, not custom implementations"
      - "Leverage query builders for complex queries"
      - "Understand N+1 problem, use includes wisely"
      - "Transactions for multi-model operations"

# Adaptation Rules
adaptation_rules:
  - condition: "pattern exists natively in stack"
    action: "suggest_native"
    priority: "high"
    message: "Use stack-native implementation instead of custom pattern"

  - condition: "custom implementation found AND native exists"
    action: "refactor_to_native"
    priority: "high"
    message: "Refactor custom implementation to use stack-native idiom"

  - condition: "pattern missing AND native exists"
    action: "suggest_native_with_example"
    priority: "medium"
    message: "Implement using stack-native features"

  - condition: "pattern missing AND no native equivalent"
    action: "suggest_custom_implementation"
    priority: "low"
    message: "Implement custom TypeScript pattern following best practices"

  - condition: "anti-pattern detected"
    action: "warn_and_suggest_alternative"
    priority: "critical"
    message: "Current implementation has known issues, see alternative"

# Common Stack Combinations
stack_combinations:
  react_full:
    primary: "react"
    common_secondary: ["redux", "react-query", "zustand"]
    pattern_notes: "React Query/SWR replaces many manual patterns for data fetching"

  angular_full:
    primary: "angular"
    common_secondary: ["rxjs", "ngrx"]
    pattern_notes: "RxJS is integral, NgRx adds Redux-like state management"

  nestjs_full:
    primary: "nestjs"
    common_secondary: ["typeorm", "prisma"]
    pattern_notes: "NestJS provides most patterns, ORM adds repository layer"

  vue_full:
    primary: "vue"
    common_secondary: ["pinia", "vueuse"]
    pattern_notes: "Pinia for state, VueUse provides composable utilities"

# Priority for suggestions
suggestion_priority:
  critical: "Anti-pattern or security issue"
  high: "Native stack alternative available, significant improvement"
  medium: "Pattern missing, would improve code quality"
  low: "Optional improvement, minimal impact"

```

### signatures/detection-rules.yaml

```yaml
version: "1.0.0"
description: Detection rules and heuristics for identifying design patterns in TypeScript/JavaScript code

# Detection Strategy:
# 1. Glob Phase: Find candidate files by naming convention
# 2. Grep Phase: Search for primary and secondary signals
# 3. Read Phase: Validate structure and relationships
# 4. Confidence Scoring: Aggregate signal strengths

# Creational Patterns
creational:
  singleton:
    naming_conventions:
      - "*Singleton*.ts"
      - "*Manager.ts"
      - "*Service.ts"
      - "*Client.ts"
      - "*Config.ts"
      - "*Instance.ts"

    primary_signals:
      - pattern: "private\\s+constructor"
        weight: 0.4
        description: "Private constructor prevents direct instantiation"

      - pattern: "static\\s+getInstance\\s*\\("
        weight: 0.35
        description: "Static getInstance method is canonical singleton signature"

      - pattern: "private\\s+static\\s+\\w+:\\s*\\w+"
        weight: 0.25
        description: "Private static instance field"

    secondary_signals:
      - pattern: "if\\s*\\(!\\w+\\.instance\\)"
        weight: 0.15
        description: "Lazy initialization check"

      - pattern: "return\\s+\\w+\\.instance"
        weight: 0.10
        description: "Returns singleton instance"

    typescript_specific:
      - pattern: "private\\s+static\\s+instance\\?:\\s*\\w+"
        description: "TypeScript optional instance field"

      - pattern: "public\\s+static\\s+getInstance\\(\\):\\s*\\w+"
        description: "Explicit return type annotation"

    anti_patterns:
      - pattern: "new\\s+\\w+\\(\\).*getInstance"
        description: "Creating new instance inside getInstance (wrong)"

    confidence_threshold: 0.70
    minimum_signals: 2

  factory-method:
    naming_conventions:
      - "*Factory.ts"
      - "*Creator.ts"
      - "*Provider.ts"
      - "*Builder.ts"

    primary_signals:
      - pattern: "create\\w+\\s*\\([^)]*\\):\\s*\\w+"
        weight: 0.35
        description: "create* method returning interface/type"

      - pattern: "abstract\\s+create\\w+"
        weight: 0.30
        description: "Abstract factory method"

      - pattern: "interface\\s+\\w+Factory"
        weight: 0.20
        description: "Factory interface definition"

    secondary_signals:
      - pattern: "class\\s+\\w+\\s+extends\\s+\\w+Factory"
        weight: 0.15
        description: "Concrete factory inheriting from abstract"

      - pattern: "return\\s+new\\s+\\w+\\("
        weight: 0.10
        description: "Factory returns new instance"

      - pattern: "switch\\s*\\([^)]*type[^)]*\\)"
        weight: 0.15
        description: "Type-based creation logic"

    typescript_specific:
      - pattern: "create\\w+<T[^>]*>"
        description: "Generic factory method"

    confidence_threshold: 0.65
    minimum_signals: 2

  abstract-factory:
    naming_conventions:
      - "*AbstractFactory.ts"
      - "*Factory.ts"
      - "*FactoryInterface.ts"

    primary_signals:
      - pattern: "abstract\\s+class\\s+\\w+Factory"
        weight: 0.30
        description: "Abstract factory class"

      - pattern: "interface\\s+\\w+Factory\\s*\\{[^}]*create\\w+[^}]*create\\w+"
        weight: 0.35
        description: "Factory interface with multiple create methods"

      - pattern: "create\\w+\\s*\\([^)]*\\):\\s*\\w+.*create\\w+\\s*\\([^)]*\\):\\s*\\w+"
        weight: 0.25
        description: "Multiple factory methods"

    secondary_signals:
      - pattern: "class\\s+\\w+\\s+implements\\s+\\w+Factory"
        weight: 0.15
        description: "Concrete factory implementing interface"

      - pattern: "family|related|product"
        weight: 0.10
        description: "Domain language suggesting related objects"

    confidence_threshold: 0.70
    minimum_signals: 2

  builder:
    naming_conventions:
      - "*Builder.ts"
      - "*ConfigBuilder.ts"
      - "*QueryBuilder.ts"

    primary_signals:
      - pattern: "\\w+\\s*\\([^)]*\\):\\s*(this|\\w+Builder)"
        weight: 0.30
        description: "Fluent interface returning this or builder type"

      - pattern: "build\\s*\\(\\):\\s*\\w+"
        weight: 0.35
        description: "Build method returning final product"

      - pattern: "with\\w+\\s*\\([^)]*\\):\\s*this"
        weight: 0.25
        description: "with* methods for setting properties"

    secondary_signals:
      - pattern: "set\\w+\\s*\\([^)]*\\):\\s*this"
        weight: 0.15
        description: "set* methods returning this"

      - pattern: "private\\s+\\w+\\?:\\s*\\w+"
        weight: 0.10
        description: "Optional private fields being built up"

    typescript_specific:
      - pattern: "class\\s+\\w+Builder<T"
        description: "Generic builder"

      - pattern: "\\): this \\{"
        description: "Explicit 'this' return type"

    confidence_threshold: 0.70
    minimum_signals: 2

  prototype:
    naming_conventions:
      - "*Prototype.ts"
      - "*Cloneable.ts"

    primary_signals:
      - pattern: "clone\\s*\\(\\):\\s*\\w+"
        weight: 0.45
        description: "Clone method signature"

      - pattern: "Object\\.create\\("
        weight: 0.25
        description: "Using Object.create for prototypal inheritance"

      - pattern: "JSON\\.parse\\(JSON\\.stringify\\("
        weight: 0.20
        description: "Deep clone via JSON (simple approach)"

    secondary_signals:
      - pattern: "\\.\\.\\."
        weight: 0.10
        description: "Spread operator for shallow copy"

      - pattern: "structuredClone\\("
        weight: 0.15
        description: "Modern structuredClone API"

    confidence_threshold: 0.60
    minimum_signals: 1

# Structural Patterns
structural:
  adapter:
    naming_conventions:
      - "*Adapter.ts"
      - "*Wrapper.ts"

    primary_signals:
      - pattern: "class\\s+\\w+Adapter\\s+implements\\s+\\w+"
        weight: 0.35
        description: "Adapter implementing target interface"

      - pattern: "private\\s+\\w+:\\s*\\w+;"
        weight: 0.25
        description: "Holds reference to adaptee"

      - pattern: "constructor\\([^)]*adaptee[^)]*\\)"
        weight: 0.30
        description: "Adaptee injected in constructor"

    secondary_signals:
      - pattern: "this\\.\\w+\\.\\w+\\("
        weight: 0.15
        description: "Delegates to adaptee"

      - pattern: "convert|transform|map"
        weight: 0.10
        description: "Conversion language in methods"

    confidence_threshold: 0.65
    minimum_signals: 2

  bridge:
    naming_conventions:
      - "*Bridge.ts"
      - "*Abstraction.ts"
      - "*Implementation.ts"

    primary_signals:
      - pattern: "protected\\s+impl:\\s*\\w+Implementation"
        weight: 0.35
        description: "Abstraction holds implementation reference"

      - pattern: "interface\\s+\\w+Implementation"
        weight: 0.30
        description: "Implementation interface"

      - pattern: "constructor\\([^)]*implementation[^)]*\\)"
        weight: 0.25
        description: "Implementation injected"

    secondary_signals:
      - pattern: "this\\.impl\\."
        weight: 0.15
        description: "Delegates to implementation"

    confidence_threshold: 0.60
    minimum_signals: 2

  composite:
    naming_conventions:
      - "*Composite.ts"
      - "*Component.ts"
      - "*Container.ts"
      - "*Group.ts"

    primary_signals:
      - pattern: "private\\s+children:\\s*\\w+\\[\\]"
        weight: 0.35
        description: "Collection of child components"

      - pattern: "add\\s*\\([^)]*\\):|remove\\s*\\([^)]*\\):"
        weight: 0.30
        description: "Methods to manage children"

      - pattern: "abstract\\s+class\\s+\\w+Component"
        weight: 0.25
        description: "Abstract component class"

    secondary_signals:
      - pattern: "children\\.forEach\\(|children\\.map\\("
        weight: 0.15
        description: "Iterates over children"

      - pattern: "getChild\\(|getChildren\\("
        weight: 0.10
        description: "Access to children"

    typescript_specific:
      - pattern: "children:\\s*Array<\\w+>"
        description: "Typed array of components"

    confidence_threshold: 0.70
    minimum_signals: 2

  decorator:
    naming_conventions:
      - "*Decorator.ts"
      - "*Wrapper.ts"

    primary_signals:
      - pattern: "class\\s+\\w+Decorator\\s+implements\\s+\\w+"
        weight: 0.30
        description: "Decorator implements same interface"

      - pattern: "protected\\s+wrapped:\\s*\\w+"
        weight: 0.30
        description: "Holds reference to wrapped object"

      - pattern: "constructor\\([^)]*wrapped[^)]*\\)"
        weight: 0.25
        description: "Wrapped object injected"

    secondary_signals:
      - pattern: "this\\.wrapped\\.\\w+\\("
        weight: 0.20
        description: "Delegates to wrapped object"

      - pattern: "super\\(wrapped\\)"
        weight: 0.15
        description: "Passes wrapped to base decorator"

    typescript_specific:
      - pattern: "@\\w+"
        description: "TypeScript decorator syntax (different usage)"

    confidence_threshold: 0.65
    minimum_signals: 2

  facade:
    naming_conventions:
      - "*Facade.ts"
      - "*API.ts"
      - "*Interface.ts"
      - "*Service.ts"

    primary_signals:
      - pattern: "private\\s+\\w+Service:\\s*\\w+;[^}]*private\\s+\\w+Service:\\s*\\w+"
        weight: 0.35
        description: "Multiple subsystem dependencies"

      - pattern: "constructor\\([^)]*,\\s*[^)]*,\\s*[^)]*\\)"
        weight: 0.25
        description: "Multiple injected dependencies"

    secondary_signals:
      - pattern: "this\\.\\w+Service\\.\\w+\\([^)]*\\);[^}]*this\\.\\w+Service\\.\\w+\\("
        weight: 0.20
        description: "Coordinates multiple subsystems"

      - pattern: "public\\s+async\\s+\\w+\\([^)]*\\)"
        weight: 0.10
        description: "Simplified public interface"

    confidence_threshold: 0.60
    minimum_signals: 2

  flyweight:
    naming_conventions:
      - "*Flyweight.ts"
      - "*Pool.ts"
      - "*Cache.ts"

    primary_signals:
      - pattern: "private\\s+static\\s+pool:\\s*Map"
        weight: 0.35
        description: "Shared pool of flyweights"

      - pattern: "getFlyweight\\s*\\([^)]*\\):\\s*\\w+"
        weight: 0.30
        description: "Factory method for shared objects"

      - pattern: "if\\s*\\(!pool\\.has\\([^)]*\\)\\)"
        weight: 0.25
        description: "Check if flyweight exists before creating"

    secondary_signals:
      - pattern: "intrinsic|extrinsic"
        weight: 0.15
        description: "Domain language for shared/unique state"

    confidence_threshold: 0.65
    minimum_signals: 2

  proxy:
    naming_conventions:
      - "*Proxy.ts"

    primary_signals:
      - pattern: "class\\s+\\w+Proxy\\s+implements\\s+\\w+"
        weight: 0.30
        description: "Proxy implements same interface as real subject"

      - pattern: "private\\s+realSubject:\\s*\\w+"
        weight: 0.30
        description: "Holds reference to real subject"

      - pattern: "lazy|cache|access|log"
        weight: 0.20
        description: "Proxy purpose keywords"

    secondary_signals:
      - pattern: "if\\s*\\(!this\\.realSubject\\)"
        weight: 0.15
        description: "Lazy initialization"

      - pattern: "this\\.realSubject\\.\\w+\\("
        weight: 0.15
        description: "Delegates to real subject"

    typescript_specific:
      - pattern: "new\\s+Proxy\\("
        description: "JavaScript Proxy object"

    confidence_threshold: 0.65
    minimum_signals: 2

# Behavioral Patterns
behavioral:
  chain-of-responsibility:
    naming_conventions:
      - "*Handler.ts"
      - "*Middleware.ts"
      - "*Chain.ts"

    primary_signals:
      - pattern: "protected\\s+next:\\s*\\w+Handler"
        weight: 0.35
        description: "Reference to next handler"

      - pattern: "setNext\\s*\\([^)]*\\):\\s*\\w+Handler"
        weight: 0.30
        description: "Method to set next handler"

      - pattern: "handle\\s*\\([^)]*\\):"
        weight: 0.25
        description: "Handle method"

    secondary_signals:
      - pattern: "if\\s*\\(this\\.next\\)"
        weight: 0.15
        description: "Checks if next handler exists"

      - pattern: "this\\.next\\.handle\\("
        weight: 0.15
        description: "Passes request to next"

    confidence_threshold: 0.70
    minimum_signals: 2

  command:
    naming_conventions:
      - "*Command.ts"
      - "*Action.ts"

    primary_signals:
      - pattern: "interface\\s+\\w+Command\\s*\\{[^}]*execute"
        weight: 0.35
        description: "Command interface with execute"

      - pattern: "execute\\s*\\(\\):"
        weight: 0.30
        description: "Execute method"

      - pattern: "undo\\s*\\(\\):"
        weight: 0.25
        description: "Undo method for reversibility"

    secondary_signals:
      - pattern: "private\\s+receiver:\\s*\\w+"
        weight: 0.15
        description: "Holds receiver reference"

      - pattern: "history|stack"
        weight: 0.10
        description: "Command history tracking"

    confidence_threshold: 0.65
    minimum_signals: 2

  iterator:
    naming_conventions:
      - "*Iterator.ts"

    primary_signals:
      - pattern: "\\[Symbol\\.iterator\\]\\(\\)"
        weight: 0.40
        description: "JavaScript iterator protocol"

      - pattern: "next\\s*\\(\\):\\s*\\{\\s*value[^}]*done"
        weight: 0.35
        description: "Iterator next method"

      - pattern: "function\\*|\\*\\w+\\s*\\("
        weight: 0.25
        description: "Generator function"

    secondary_signals:
      - pattern: "yield"
        weight: 0.15
        description: "Generator yield"

      - pattern: "implements\\s+Iterator<"
        weight: 0.15
        description: "Implements Iterator interface"

    confidence_threshold: 0.65
    minimum_signals: 1

  mediator:
    naming_conventions:
      - "*Mediator.ts"
      - "*Controller.ts"
      - "*Coordinator.ts"

    primary_signals:
      - pattern: "class\\s+\\w+Mediator"
        weight: 0.30
        description: "Mediator class"

      - pattern: "private\\s+colleagues:\\s*\\w+\\[\\]"
        weight: 0.30
        description: "Collection of colleagues"

      - pattern: "notify\\s*\\([^)]*sender[^)]*\\)"
        weight: 0.30
        description: "Notify method with sender"

    secondary_signals:
      - pattern: "register\\w+\\(|add\\w+\\("
        weight: 0.15
        description: "Register colleagues"

    confidence_threshold: 0.65
    minimum_signals: 2

  memento:
    naming_conventions:
      - "*Memento.ts"
      - "*Snapshot.ts"
      - "*Caretaker.ts"

    primary_signals:
      - pattern: "save\\s*\\(\\):\\s*\\w+Memento"
        weight: 0.35
        description: "Save state to memento"

      - pattern: "restore\\s*\\([^)]*memento[^)]*\\)"
        weight: 0.35
        description: "Restore from memento"

      - pattern: "class\\s+\\w+Memento"
        weight: 0.20
        description: "Memento class"

    secondary_signals:
      - pattern: "private\\s+state:"
        weight: 0.15
        description: "Encapsulated state"

      - pattern: "history:\\s*\\w+\\[\\]"
        weight: 0.10
        description: "History of mementos"

    confidence_threshold: 0.70
    minimum_signals: 2

  observer:
    naming_conventions:
      - "*Observer.ts"
      - "*Subject.ts"
      - "*Publisher.ts"
      - "*Subscriber.ts"
      - "*Event*.ts"

    primary_signals:
      - pattern: "subscribe\\s*\\([^)]*\\):|attach\\s*\\([^)]*\\):"
        weight: 0.30
        description: "Subscribe method"

      - pattern: "unsubscribe\\s*\\([^)]*\\):|detach\\s*\\([^)]*\\):"
        weight: 0.25
        description: "Unsubscribe method"

      - pattern: "notify\\s*\\(\\):|emit\\s*\\("
        weight: 0.30
        description: "Notify/emit method"

    secondary_signals:
      - pattern: "private\\s+observers:\\s*\\w+\\[\\]"
        weight: 0.20
        description: "Collection of observers"

      - pattern: "observers\\.forEach\\("
        weight: 0.15
        description: "Iterates over observers to notify"

    typescript_specific:
      - pattern: "Subject<"
        description: "RxJS Subject (common in Angular/React)"

    confidence_threshold: 0.70
    minimum_signals: 2

  state:
    naming_conventions:
      - "*State.ts"
      - "*Context.ts"

    primary_signals:
      - pattern: "interface\\s+\\w+State"
        weight: 0.30
        description: "State interface"

      - pattern: "private\\s+state:\\s*\\w+State"
        weight: 0.30
        description: "Context holds current state"

      - pattern: "setState\\s*\\([^)]*\\):|changeState\\s*\\([^)]*\\):"
        weight: 0.30
        description: "Method to change state"

    secondary_signals:
      - pattern: "this\\.state\\.handle\\("
        weight: 0.15
        description: "Delegates to state"

      - pattern: "class\\s+\\w+State\\s+implements\\s+\\w+State"
        weight: 0.15
        description: "Concrete state classes"

    confidence_threshold: 0.70
    minimum_signals: 2

  strategy:
    naming_conventions:
      - "*Strategy.ts"
      - "*Policy.ts"
      - "*Algorithm.ts"

    primary_signals:
      - pattern: "interface\\s+\\w+Strategy"
        weight: 0.35
        description: "Strategy interface"

      - pattern: "private\\s+strategy:\\s*\\w+Strategy"
        weight: 0.30
        description: "Context holds strategy"

      - pattern: "setStrategy\\s*\\([^)]*\\):"
        weight: 0.25
        description: "Method to set strategy"

    secondary_signals:
      - pattern: "this\\.strategy\\.execute\\("
        weight: 0.15
        description: "Delegates to strategy"

      - pattern: "class\\s+\\w+Strategy\\s+implements\\s+\\w+Strategy"
        weight: 0.15
        description: "Concrete strategies"

    confidence_threshold: 0.70
    minimum_signals: 2

  template-method:
    naming_conventions:
      - "*Template.ts"
      - "*Abstract*.ts"

    primary_signals:
      - pattern: "abstract\\s+class"
        weight: 0.30
        description: "Abstract class with template"

      - pattern: "abstract\\s+\\w+\\s*\\(\\):"
        weight: 0.30
        description: "Abstract primitive operations"

      - pattern: "protected\\s+\\w+\\s*\\(\\):"
        weight: 0.20
        description: "Hook methods"

    secondary_signals:
      - pattern: "this\\.\\w+\\(\\);[^}]*this\\.\\w+\\(\\);"
        weight: 0.15
        description: "Template calls primitive operations"

      - pattern: "final\\s+|\\btemplate\\b"
        weight: 0.10
        description: "Template method should be final (not overridden)"

    confidence_threshold: 0.65
    minimum_signals: 2

  visitor:
    naming_conventions:
      - "*Visitor.ts"

    primary_signals:
      - pattern: "interface\\s+\\w+Visitor\\s*\\{[^}]*visit\\w+"
        weight: 0.35
        description: "Visitor interface with visit methods"

      - pattern: "visit\\w+\\s*\\([^)]*:\\s*\\w+\\)"
        weight: 0.30
        description: "Visit methods for each element type"

      - pattern: "accept\\s*\\([^)]*visitor[^)]*\\)"
        weight: 0.30
        description: "Elements accept visitor"

    secondary_signals:
      - pattern: "visitor\\.visit\\w+\\(this\\)"
        weight: 0.15
        description: "Double dispatch pattern"

    confidence_threshold: 0.70
    minimum_signals: 2

  interpreter:
    naming_conventions:
      - "*Interpreter.ts"
      - "*Expression.ts"
      - "*Parser.ts"

    primary_signals:
      - pattern: "interface\\s+\\w+Expression"
        weight: 0.30
        description: "Expression interface"

      - pattern: "interpret\\s*\\([^)]*context[^)]*\\)"
        weight: 0.35
        description: "Interpret method with context"

      - pattern: "abstract\\s+class\\s+\\w+Expression"
        weight: 0.25
        description: "Abstract expression"

    secondary_signals:
      - pattern: "class\\s+Terminal\\w+|class\\s+NonTerminal\\w+"
        weight: 0.15
        description: "Terminal and non-terminal expressions"

      - pattern: "parse\\s*\\("
        weight: 0.10
        description: "Parser for grammar"

    confidence_threshold: 0.60
    minimum_signals: 2

# Confidence Calculation
confidence_calculation:
  formula: "sum(matched_signal_weights) / sum(all_possible_weights)"
  adjustments:
    - "If pattern name matches naming convention: +0.15"
    - "If stack has native equivalent and not used: -0.20"
    - "If anti-pattern detected: -0.30"
    - "If typescript-specific signals present: +0.10"

# Output Format for Detection Results
detection_output:
  file: "path/to/file.ts"
  pattern: "singleton"
  lines: "5-28"
  confidence: 0.85
  matched_signals:
    - signal: "private constructor"
      weight: 0.4
    - signal: "static getInstance"
      weight: 0.35
  stack_context:
    native_alternative: "Context API"
    recommendation: "Consider using React Context for better testability"

```

### signatures/code-smells.yaml

```yaml
version: "1.0.0"
description: Mapping from code smells to applicable design patterns with detection rules and rationale

# Code Smell Categories
categories:
  - bloaters           # Code that has grown too large
  - oo_abusers         # Misuse of object-oriented principles
  - change_preventers  # Changes require modifications in many places
  - dispensables       # Pointless code that should be removed
  - couplers           # Excessive coupling between classes

# Code Smells with Pattern Suggestions
code_smells:
  switch_on_type:
    category: oo_abusers
    description: "Switch statement (or if-else chain) discriminating on object type or kind"
    severity: medium

    detection:
      patterns:
        - "switch\\s*\\([^)]*\\.type\\)"
        - "switch\\s*\\([^)]*\\.kind\\)"
        - "if\\s*\\([^)]*instanceof\\s+\\w+\\).*else\\s+if\\s*\\([^)]*instanceof"
      context: "Function or method with >3 cases"

    suggested_patterns:
      - pattern: strategy
        priority: high
        rationale: "Replace conditional logic with strategy objects"
        example: |
          // Before (smell)
          switch (paymentType) {
            case 'credit': return processCreditCard();
            case 'paypal': return processPaypal();
            case 'crypto': return processCrypto();
          }

          // After (Strategy)
          const strategy = strategies[paymentType];
          return strategy.process();

      - pattern: factory-method
        priority: medium
        rationale: "If creating objects based on type"
        example: |
          // Before (smell)
          switch (type) {
            case 'A': return new ProductA();
            case 'B': return new ProductB();
          }

          // After (Factory)
          return ProductFactory.create(type);

  long_parameter_list:
    category: bloaters
    description: "Function/constructor with more than 4 parameters"
    severity: medium

    detection:
      patterns:
        - "function\\s+\\w+\\s*\\([^)]{100,}\\)"  # Heuristic: >100 chars
        - "constructor\\s*\\([^)]{80,}\\)"
      context: "Count commas in parameter list"

    suggested_patterns:
      - pattern: builder
        priority: high
        rationale: "Fluent interface for step-by-step construction"
        example: |
          // Before (smell)
          new House(walls, doors, windows, roof, garage, pool, garden);

          // After (Builder)
          new HouseBuilder()
            .setWalls(walls)
            .setDoors(doors)
            .build();

      - pattern: parameter-object
        priority: medium
        rationale: "Group related parameters into object"
        example: |
          // Before (smell)
          function createUser(name, email, age, address, phone, role) { }

          // After (Parameter Object)
          function createUser(userData: UserData) { }

  global_state_access:
    category: couplers
    description: "Scattered access to global variables or singletons"
    severity: high

    detection:
      patterns:
        - "window\\.[A-Z]\\w+"
        - "global\\.[A-Z]\\w+"
        - "\\w+\\.getInstance\\(\\)"
      context: "Outside of configuration/initialization files"

    suggested_patterns:
      - pattern: dependency-injection
        priority: high
        rationale: "Inject dependencies instead of global access"
        example: |
          // Before (smell)
          const config = Config.getInstance();

          // After (DI)
          class Service {
            constructor(private config: Config) {}
          }

      - pattern: singleton
        priority: low
        rationale: "If truly global state is needed (use sparingly)"
        note: "Consider framework-native alternatives (React Context, Angular Services)"

  duplicated_conditionals_on_state:
    category: change_preventers
    description: "Same state checks scattered across methods"
    severity: medium

    detection:
      patterns:
        - "if\\s*\\([^)]*\\.state\\s*===\\s*['\"]\\w+['\"]\\).*if\\s*\\([^)]*\\.state\\s*===\\s*['\"]\\w+['\"]\\)"
        - "switch\\s*\\([^)]*\\.status\\)"
      context: "Multiple methods with identical state checks"

    suggested_patterns:
      - pattern: state
        priority: high
        rationale: "Encapsulate state-dependent behavior in state classes"
        example: |
          // Before (smell)
          if (order.status === 'draft') { /* ... */ }
          else if (order.status === 'submitted') { /* ... */ }

          // After (State pattern)
          order.state.process(); // Behavior varies by state object

  scattered_notification_logic:
    category: change_preventers
    description: "Manual notification loops in multiple places"
    severity: medium

    detection:
      patterns:
        - "listeners\\.forEach\\(\\s*\\w+\\s*=>\\s*\\w+\\.\\w+\\(\\)"
        - "for\\s*\\([^)]*observers[^)]*\\).*\\.update\\("
      context: "Multiple locations with similar notification code"

    suggested_patterns:
      - pattern: observer
        priority: high
        rationale: "Centralize subscription and notification mechanism"
        example: |
          // Before (smell)
          for (const listener of this.listeners) {
            listener.notify(data);
          }

          // After (Observer)
          this.subject.notify(data); // Handles all observers

      - pattern: event-emitter
        priority: medium
        rationale: "Use built-in EventEmitter (Node.js) or EventTarget"
        stack_native:
          javascript: "EventTarget, EventEmitter"
          rxjs: "Subject, BehaviorSubject"

  complex_object_creation:
    category: bloaters
    description: "Object construction requires many steps or conditional logic"
    severity: medium

    detection:
      patterns:
        - "new\\s+\\w+\\([^)]{80,}\\)"  # Long constructor call
        - "const\\s+\\w+\\s*=\\s*new\\s+\\w+\\(\\);[^}]{50,}\\w+\\.set\\w+"
      context: "Construction spans multiple lines with setters"

    suggested_patterns:
      - pattern: builder
        priority: high
        rationale: "Step-by-step construction with fluent interface"

      - pattern: factory-method
        priority: medium
        rationale: "Encapsulate creation logic"

      - pattern: abstract-factory
        priority: low
        rationale: "If creating families of related objects"

  tight_coupling_to_concrete_classes:
    category: couplers
    description: "Direct instantiation of concrete classes throughout codebase"
    severity: medium

    detection:
      patterns:
        - "new\\s+Concrete\\w+\\("
        - "new\\s+\\w+Impl\\("
      context: "Multiple files instantiating same concrete classes"

    suggested_patterns:
      - pattern: factory-method
        priority: high
        rationale: "Depend on interfaces, not concrete classes"

      - pattern: dependency-injection
        priority: high
        rationale: "Inject dependencies instead of creating them"

      - pattern: adapter
        priority: medium
        rationale: "If integrating incompatible third-party code"

  repetitive_interface_conversions:
    category: dispensables
    description: "Manual conversion between incompatible interfaces"
    severity: low

    detection:
      patterns:
        - "\\{\\s*\\w+:\\s*\\w+\\.\\w+,.*\\w+:\\s*\\w+\\.\\w+"  # Object mapping
      context: "Same mapping logic repeated in multiple places"

    suggested_patterns:
      - pattern: adapter
        priority: high
        rationale: "Single adapter class for interface conversion"

  deep_nesting_for_feature_addition:
    category: change_preventers
    description: "Adding features requires modifying deeply nested code"
    severity: medium

    detection:
      patterns:
        - "class\\s+\\w+\\s+extends\\s+\\w+\\s+extends\\s+\\w+"  # Multi-level inheritance
      context: "Inheritance hierarchy >3 levels deep"

    suggested_patterns:
      - pattern: decorator
        priority: high
        rationale: "Compose behavior dynamically instead of deep inheritance"

      - pattern: strategy
        priority: medium
        rationale: "If behavior variants are swapped at runtime"

  large_class_many_responsibilities:
    category: bloaters
    description: "Class has too many responsibilities (God Object)"
    severity: high

    detection:
      patterns:
        - "class\\s+\\w+\\s*\\{"
      context: "Class >300 lines or >20 methods"

    suggested_patterns:
      - pattern: facade
        priority: high
        rationale: "If class coordinates multiple subsystems"

      - pattern: strategy
        priority: medium
        rationale: "Extract varying behavior into strategies"

      - pattern: extract-class
        priority: high
        rationale: "Split into multiple focused classes"

  complex_conditional_logic:
    category: bloaters
    description: "Deeply nested conditionals or complex boolean expressions"
    severity: medium

    detection:
      patterns:
        - "if\\s*\\([^)]*&&[^)]*&&[^)]*\\)"  # Multiple conditions
        - "if\\s*\\(.*if\\s*\\(.*if\\s*\\("  # Nested ifs
      context: "Cyclomatic complexity >10"

    suggested_patterns:
      - pattern: strategy
        priority: high
        rationale: "Replace conditional with strategy object"

      - pattern: state
        priority: medium
        rationale: "If conditionals check object state"

      - pattern: chain-of-responsibility
        priority: low
        rationale: "If processing steps can be chained"

  data_clumps:
    category: bloaters
    description: "Same group of parameters appears together frequently"
    severity: low

    detection:
      patterns:
        - "function\\s+\\w+\\([^)]*userId[^)]*userName[^)]*userEmail[^)]*\\)"
      context: "Same 3+ parameters in multiple functions"

    suggested_patterns:
      - pattern: parameter-object
        priority: high
        rationale: "Group related parameters into object"

      - pattern: builder
        priority: medium
        rationale: "If object construction is complex"

  manual_resource_management:
    category: change_preventers
    description: "Manual open/close, connect/disconnect, etc."
    severity: medium

    detection:
      patterns:
        - "open\\([^)]*\\);.*close\\("
        - "connect\\([^)]*\\);.*disconnect\\("
      context: "Scattered resource management logic"

    suggested_patterns:
      - pattern: template-method
        priority: high
        rationale: "Template ensures proper initialization/cleanup"

      - pattern: proxy
        priority: medium
        rationale: "Proxy manages resource lifecycle"

  feature_envy:
    category: couplers
    description: "Method uses more features of another class than its own"
    severity: medium

    detection:
      patterns:
        - "this\\.(\\w+\\.){3,}"  # Multiple chained accesses
      context: "Method heavily accesses another object's data"

    suggested_patterns:
      - pattern: extract-method
        priority: high
        rationale: "Move method to the class it envies"

      - pattern: visitor
        priority: low
        rationale: "If operation needs to be external"

  shotgun_surgery:
    category: change_preventers
    description: "Single change requires modifying many classes"
    severity: high

    detection:
      manual: true
      context: "Feature addition requires >5 file changes"

    suggested_patterns:
      - pattern: facade
        priority: high
        rationale: "Centralize interface to subsystem"

      - pattern: mediator
        priority: medium
        rationale: "Centralize communication between objects"

      - pattern: observer
        priority: medium
        rationale: "Decouple event sources from handlers"

  parallel_inheritance_hierarchies:
    category: change_preventers
    description: "Adding subclass to one hierarchy requires adding to another"
    severity: medium

    detection:
      manual: true
      context: "Two inheritance trees grow together"

    suggested_patterns:
      - pattern: bridge
        priority: high
        rationale: "Separate abstraction from implementation"

  refused_bequest:
    category: oo_abusers
    description: "Subclass doesn't use inherited methods"
    severity: low

    detection:
      manual: true
      context: "Subclass throws errors or leaves methods empty"

    suggested_patterns:
      - pattern: composition-over-inheritance
        priority: high
        rationale: "Use composition instead of inheritance"

      - pattern: strategy
        priority: medium
        rationale: "Delegate to strategy object"

# Detection Priority Rules
detection_rules:
  priority_high:
    - "Affects >5 files"
    - "Security implications"
    - "Performance bottleneck"
    - "Blocks new features"

  priority_medium:
    - "Affects 2-5 files"
    - "Moderate complexity increase"
    - "Makes testing harder"

  priority_low:
    - "Affects 1 file"
    - "Minor code quality issue"
    - "Cosmetic improvement"

# Refactoring Impact Assessment
impact_assessment:
  effort:
    low: "< 2 hours, single file"
    medium: "2-8 hours, multiple files"
    high: "> 8 hours, architectural change"

  risk:
    low: "Localized change, comprehensive tests exist"
    medium: "Multiple components affected, partial test coverage"
    high: "Core functionality, limited tests"

  benefit:
    low: "Minor code quality improvement"
    medium: "Improved maintainability, easier testing"
    high: "Significant complexity reduction, enables new features"

# Stack-Specific Smell Detection
stack_specific_smells:
  react:
    - smell: "Class components with complex lifecycle methods"
      pattern: hooks
      note: "Migrate to functional components with hooks"

    - smell: "Props drilling >3 levels"
      pattern: context
      note: "Use Context API for shared state"

  angular:
    - smell: "Manual subscription management"
      pattern: async-pipe
      note: "Use async pipe in templates"

    - smell: "Services with getInstance()"
      pattern: dependency-injection
      note: "Use Angular DI with @Injectable()"

  nestjs:
    - smell: "Manual middleware chaining"
      pattern: guards-interceptors
      note: "Use NestJS Guards/Interceptors"

  express:
    - smell: "Nested callback chains"
      pattern: async-await
      note: "Use async/await or Promises"

```

### checklists/pattern-evaluation.md

```markdown
---
title: "Design Pattern Quality Evaluation Checklist"
description: "Systematic scoring criteria for evaluating design pattern implementation quality"
tags: [cheatsheet, design-patterns, code-review]
---

# Design Pattern Quality Evaluation Checklist

Systematic criteria for evaluating the quality of design pattern implementations.

## Evaluation Criteria

Each criterion is scored **0-10**, where:
- **9-10**: Exemplary, reference-quality implementation
- **7-8**: Good, minor improvements possible
- **5-6**: Acceptable, notable issues to address
- **3-4**: Problematic, significant refactoring needed
- **0-2**: Incorrect or severely flawed

**Overall Score** = Average of all criteria scores

---

## 1. Correctness (0-10)

**Question**: Does the implementation correctly follow the canonical pattern structure?

### Scoring Guidelines

| Score | Description |
|-------|-------------|
| 9-10  | Perfect adherence to pattern structure, all roles present and correctly implemented |
| 7-8   | Minor deviations that don't compromise pattern intent |
| 5-6   | Some structural issues but pattern is recognizable and functional |
| 3-4   | Significant structural problems, pattern only partially implemented |
| 0-2   | Incorrect implementation, doesn't match pattern at all |

### Checklist

**Singleton**:
- [ ] Private constructor
- [ ] Static getInstance() method
- [ ] Private static instance field
- [ ] Thread-safe (if relevant)
- [ ] Returns same instance every time

**Observer**:
- [ ] Subject interface with attach/detach/notify
- [ ] Observer interface with update method
- [ ] Subject maintains list of observers
- [ ] Notify calls update on all observers
- [ ] Observers can be added/removed dynamically

**Strategy**:
- [ ] Strategy interface defining algorithm
- [ ] Context holds strategy reference
- [ ] Context delegates to strategy
- [ ] Strategies are interchangeable
- [ ] Client can set strategy at runtime

**Factory Method**:
- [ ] Factory method returns interface/abstract class
- [ ] Subclasses override factory method
- [ ] Client code depends on interface, not concrete classes
- [ ] Creation logic is encapsulated

**Decorator**:
- [ ] Decorator implements same interface as wrapped object
- [ ] Decorator holds reference to wrapped object
- [ ] Decorator delegates to wrapped object
- [ ] Can stack multiple decorators
- [ ] Maintains interface contract

### Common Mistakes (Deductions)

- **-2**: Missing key component (e.g., Singleton without private constructor)
- **-3**: Incorrect delegation (e.g., Decorator not calling wrapped object)
- **-4**: Breaking pattern invariants (e.g., Singleton returning different instances)

---

## 2. Testability (0-10)

**Question**: How easy is it to write unit tests for this implementation?

### Scoring Guidelines

| Score | Description |
|-------|-------------|
| 9-10  | Easily mockable, injectable dependencies, no global state |
| 7-8   | Testable with minor setup, some coupling exists |
| 5-6   | Requires significant test setup, moderate coupling |
| 3-4   | Hard to test, tight coupling, global state |
| 0-2   | Nearly impossible to test, static dependencies, no injection points |

### Checklist

- [ ] Dependencies are injected (not created internally)
- [ ] Interfaces are used (can be mocked)
- [ ] No hard-coded dependencies
- [ ] No global state access (or minimal)
- [ ] Test isolation is possible (tests don't affect each other)
- [ ] No static methods that can't be mocked
- [ ] Side effects are minimized or controllable

### Red Flags (Deductions)

- **-2**: Using `getInstance()` instead of dependency injection
- **-2**: Hard-coded concrete class instantiation
- **-3**: Accessing global state (window, global, process.env in business logic)
- **-3**: Static methods with side effects
- **-4**: No way to inject test doubles

### Examples

**Bad Testability (Score: 2/10)**:
```typescript
class PaymentService {
  processPayment(amount: number) {
    // Hard to test: creates dependency internally
    const gateway = PaymentGateway.getInstance();
    // Hard to test: accesses global config
    const apiKey = process.env.PAYMENT_API_KEY;
    return gateway.charge(amount, apiKey);
  }
}
```

**Good Testability (Score: 9/10)**:
```typescript
class PaymentService {
  constructor(
    private gateway: IPaymentGateway,
    private config: Config
  ) {}

  processPayment(amount: number) {
    const apiKey = this.config.getPaymentApiKey();
    return this.gateway.charge(amount, apiKey);
  }
}

// Easy to test with mocks
const mockGateway = { charge: jest.fn() };
const mockConfig = { getPaymentApiKey: () => 'test-key' };
const service = new PaymentService(mockGateway, mockConfig);
```

---

## 3. Single Responsibility Principle (0-10)

**Question**: Does the component have one, clearly defined responsibility?

### Scoring Guidelines

| Score | Description |
|-------|-------------|
| 9-10  | Single, focused responsibility; class has one reason to change |
| 7-8   | Mostly focused, minor secondary concerns |
| 5-6   | Multiple related responsibilities |
| 3-4   | Several unrelated responsibilities |
| 0-2   | God class with many responsibilities |

### Checklist

- [ ] Class/module has one clear purpose
- [ ] All methods relate to the primary responsibility
- [ ] Changing one requirement doesn't necessitate changing this class
- [ ] Class name clearly reflects its responsibility
- [ ] No "and" in class name or description (e.g., "UserManagerAndLogger" is bad)

### Red Flags (Deductions)

- **-2**: Class handles 2 distinct concerns
- **-3**: Class handles 3+ concerns
- **-4**: God class (>20 methods, >300 lines)
- **-1**: Methods unrelated to primary responsibility

### Examples

**Poor SRP (Score: 3/10)**:
```typescript
class UserService {
  createUser(data: UserData) { /* ... */ }
  validateEmail(email: string) { /* ... */ }
  sendWelcomeEmail(user: User) { /* ... */ }
  logUserActivity(activity: string) { /* ... */ }
  generateReport(userId: string) { /* ... */ }
  // Too many responsibilities: creation, validation, email, logging, reporting
}
```

**Good SRP (Score: 9/10)**:
```typescript
class UserService {
  constructor(
    private validator: UserValidator,
    private emailService: EmailService,
    private logger: Logger
  ) {}

  createUser(data: UserData): User {
    // Focuses only on user creation orchestration
    this.validator.validate(data);
    const user = new User(data);
    this.emailService.sendWelcomeEmail(user);
    this.logger.logActivity('user_created', user.id);
    return user;
  }
}
```

---

## 4. Open/Closed Principle (0-10)

**Question**: Can the component be extended without modifying its source code?

### Scoring Guidelines

| Score | Description |
|-------|-------------|
| 9-10  | Fully extensible via inheritance or composition, no modification needed |
| 7-8   | Mostly extensible, minor modifications might be needed |
| 5-6   | Some extension points exist but limited |
| 3-4   | Hard to extend, requires modification in multiple places |
| 0-2   | Closed for extension, must modify source code |

### Checklist

- [ ] Uses interfaces or abstract classes
- [ ] New behavior can be added via new classes, not modifications
- [ ] Configuration or strategy pattern for varying behavior
- [ ] No switch statements on types (if adding new type requires modification)
- [ ] Dependency inversion (depends on abstractions)

### Red Flags (Deductions)

- **-2**: Switch on type (adding new type requires modification)
- **-3**: No interfaces (concrete dependencies everywhere)
- **-3**: Hard-coded behavior (no extension points)
- **-4**: Modifying existing methods is the only way to add features

### Examples

**Closed for Extension (Score: 2/10)**:
```typescript
class PaymentProcessor {
  process(type: string, amount: number) {
    switch (type) {
      case 'credit': return this.processCreditCard(amount);
      case 'paypal': return this.processPaypal(amount);
      // Adding crypto payment requires modifying this class
    }
  }
}
```

**Open for Extension (Score: 9/10)**:
```typescript
interface PaymentStrategy {
  process(amount: number): Promise<Receipt>;
}

class PaymentProcessor {
  constructor(private strategies: Map<string, PaymentStrategy>) {}

  process(type: string, amount: number) {
    const strategy = this.strategies.get(type);
    if (!strategy) throw new Error(`Unknown payment type: ${type}`);
    return strategy.process(amount);
  }
}

// Add new payment method without modifying PaymentProcessor
class CryptoPaymentStrategy implements PaymentStrategy {
  process(amount: number) { /* ... */ }
}
```

---

## 5. Documentation (0-10)

**Question**: Is the implementation well-documented with clear intent and usage?

### Scoring Guidelines

| Score | Description |
|-------|-------------|
| 9-10  | Comprehensive documentation: intent, usage, examples, edge cases |
| 7-8   | Good documentation, covers main use cases |
| 5-6   | Basic documentation, minimal but present |
| 3-4   | Sparse documentation, unclear intent |
| 0-2   | No documentation or misleading documentation |

### Checklist

- [ ] Class/interface has JSDoc/TSDoc comment explaining purpose
- [ ] Pattern intent is documented ("This is a Singleton because...")
- [ ] Public methods have documentation
- [ ] Complex logic has inline comments
- [ ] Usage examples are provided (in README or comments)
- [ ] Invariants and constraints are documented
- [ ] Naming is self-documenting (clear, descriptive names)

### Red Flags (Deductions)

- **-2**: No class-level documentation
- **-2**: Public API methods undocumented
- **-3**: Cryptic naming (x, foo, temp, data)
- **-1**: Complex logic without explanation

### Examples

**Poor Documentation (Score: 2/10)**:
```typescript
class S {
  private static i: S;
  private constructor() {}
  static get() {
    if (!S.i) S.i = new S();
    return S.i;
  }
  do(x: any) { /* ... */ }
}
```

**Good Documentation (Score: 9/10)**:
```typescript
/**
 * Configuration service implemented as a Singleton to ensure
 * all components share the same configuration state.
 *
 * Use `ConfigService.getInstance()` to access the singleton instance.
 *
 * @example
 * const config = ConfigService.getInstance();
 * const apiUrl = config.get('API_URL');
 */
class ConfigService {
  private static instance: ConfigService;

  /**
   * Private constructor prevents direct instantiation.
   * Use `getInstance()` instead.
   */
  private constructor() {
    // Load configuration from environment
  }

  /**
   * Returns the singleton instance of ConfigService.
   * Creates the instance on first call (lazy initialization).
   *
   * @returns The singleton ConfigService instance
   */
  public static getInstance(): ConfigService {
    if (!ConfigService.instance) {
      ConfigService.instance = new ConfigService();
    }
    return ConfigService.instance;
  }

  /**
   * Retrieves a configuration value by key.
   *
   * @param key - Configuration key
   * @returns Configuration value or undefined if not found
   */
  public get(key: string): string | undefined {
    return process.env[key];
  }
}
```

---

## Pattern-Specific Evaluation

### Singleton Specific

**Additional Checklist**:
- [ ] Lazy initialization (if appropriate)
- [ ] Thread-safety considered (less critical in JS)
- [ ] Subclassing is prevented or controlled
- [ ] No public constructor
- [ ] Reset mechanism for tests (or DI alternative mentioned)

**Deductions**:
- **-3**: Public constructor (defeats purpose)
- **-2**: Multiple getInstance() methods returning different instances
- **-2**: No consideration of test isolation

### Observer Specific

**Additional Checklist**:
- [ ] Observers can unsubscribe
- [ ] No memory leaks (observers are properly removed)
- [ ] Notification order is deterministic (if it matters)
- [ ] Observers don't depend on notification order
- [ ] Subject doesn't know concrete observer types

**Deductions**:
- **-3**: No unsubscribe mechanism (memory leak risk)
- **-2**: Subject depends on concrete observer types
- **-2**: Notification order matters but isn't guaranteed

### Strategy Specific

**Additional Checklist**:
- [ ] Strategies implement common interface
- [ ] Context doesn't depend on concrete strategies
- [ ] Strategies are interchangeable
- [ ] Strategy can be set at runtime
- [ ] Strategies don't share state (unless explicitly designed to)

**Deductions**:
- **-3**: Context depends on concrete strategies
- **-2**: Strategies are not truly interchangeable
- **-2**: No way to change strategy at runtime

---

## Overall Assessment Formula

```
Overall Score = (
  Correctness × 0.30 +
  Testability × 0.25 +
  Single Responsibility × 0.20 +
  Open/Closed × 0.15 +
  Documentation × 0.10
) / 5
```

**Weighted** because correctness is most important, followed by testability.

---

## Interpretation Guide

| Overall Score | Interpretation | Action |
|--------------|----------------|--------|
| 9.0 - 10.0   | Excellent | Reference-quality, minimal changes needed |
| 7.0 - 8.9    | Good | Minor improvements, production-ready |
| 5.0 - 6.9    | Acceptable | Notable issues, refactoring recommended |
| 3.0 - 4.9    | Poor | Significant problems, refactoring required |
| 0.0 - 2.9    | Critical | Fundamentally flawed, redesign needed |

---

## Example Evaluation Report

### Pattern: Singleton
**File**: `src/services/config-singleton.ts`
**Lines**: 5-34

#### Scores

| Criterion | Score | Rationale |
|-----------|-------|-----------|
| Correctness | 8/10 | Implements singleton correctly, minor: no thread-safety (not critical in JS) |
| Testability | 4/10 | Hard to mock, no reset mechanism, global state makes tests interdependent |
| Single Responsibility | 9/10 | Focuses solely on configuration management |
| Open/Closed | 7/10 | Can add new config keys, but config sources are hard-coded |
| Documentation | 6/10 | Has JSDoc but missing rationale for singleton choice |

**Overall Score**: **6.8/10** (Acceptable)

#### Issues Identified

1. **High Priority**: Add `resetInstance()` method for test isolation
   - Current: Tests must run in specific order
   - Fix: Add `public static resetInstance()` guarded by environment check

2. **Medium Priority**: Document singleton rationale
   - Current: Unclear why global state is necessary
   - Fix: Add JSDoc explaining choice (e.g., "Singleton ensures consistent config across all services")

3. **Low Priority**: Consider dependency injection alternative
   - Current: Hard to test, tight coupling
   - Recommendation: Evaluate using DI container or React Context

#### Recommendations

```typescript
// Add test-friendly reset
public static resetInstance(): void {
  if (process.env.NODE_ENV === 'test') {
    ConfigService.instance = null!;
  }
}

// Better yet: refactor to DI
class ConfigService {
  constructor(private envVars: EnvVars) {}
}

// Inject in DI container or provider
const config = new ConfigService(process.env);
```

---

## Usage in Skill

When the design-patterns skill runs in **Evaluation Mode**, it:

1. Identifies which pattern is implemented
2. Applies relevant checklist items
3. Scores each criterion (0-10)
4. Calculates weighted overall score
5. Generates detailed report with:
   - Scores table
   - Issues found (priority-ranked)
   - Specific recommendations with code examples
   - Stack-native alternatives if applicable

---

## References

- *Clean Code* by Robert C. Martin (SOLID principles)
- *Refactoring: Improving the Design of Existing Code* by Martin Fowler
- *Design Patterns: Elements of Reusable Object-Oriented Software* (Gang of Four)

```

### reference/patterns-index.yaml

```yaml
version: "1.0.0"
total_patterns: 23
description: Machine-readable index of Gang of Four design patterns for TypeScript/JavaScript

categories:
  creational:
    - singleton
    - factory-method
    - abstract-factory
    - builder
    - prototype
  structural:
    - adapter
    - bridge
    - composite
    - decorator
    - facade
    - flyweight
    - proxy
  behavioral:
    - chain-of-responsibility
    - command
    - iterator
    - mediator
    - memento
    - observer
    - state
    - strategy
    - template-method
    - visitor
    - interpreter

pattern_metadata:
  # Creational Patterns
  singleton:
    difficulty: 1
    use_frequency: high
    detection_confidence: 0.85
    typical_files: ["*Manager.ts", "*Service.ts", "*Client.ts", "*Config.ts"]
    primary_signals: ["private constructor", "static getInstance", "private static instance"]
    anti_patterns: ["hard to test", "global state", "tight coupling"]
    related: [dependency-injection]
    stack_native:
      react: "Context API"
      angular: "Injectable services"
      nestjs: "@Injectable() decorator"

  factory-method:
    difficulty: 2
    use_frequency: high
    detection_confidence: 0.75
    typical_files: ["*Factory.ts", "*Creator.ts", "*Provider.ts"]
    primary_signals: ["create* method", "returns interface/abstract class", "subclass decides instantiation"]
    anti_patterns: ["simple factory confusion", "too many parameters"]
    related: [abstract-factory, builder]

  abstract-factory:
    difficulty: 3
    use_frequency: medium
    detection_confidence: 0.70
    typical_files: ["*Factory.ts", "*AbstractFactory.ts"]
    primary_signals: ["multiple create* methods", "family of related objects", "interface for factory"]
    anti_patterns: ["complexity overhead", "rigid product families"]
    related: [factory-method, prototype]

  builder:
    difficulty: 2
    use_frequency: high
    detection_confidence: 0.80
    typical_files: ["*Builder.ts"]
    primary_signals: ["fluent interface", "method chaining", "build() method", "step-by-step construction"]
    anti_patterns: ["incomplete builders", "mutable builders"]
    related: [factory-method]
    common_use_cases: ["query builders", "request builders", "complex configuration"]

  prototype:
    difficulty: 2
    use_frequency: low
    detection_confidence: 0.65
    typical_files: ["*Prototype.ts"]
    primary_signals: ["clone() method", "deep copy", "Object.create()"]
    anti_patterns: ["shallow vs deep copy confusion", "circular references"]
    related: [factory-method]

  # Structural Patterns
  adapter:
    difficulty: 2
    use_frequency: high
    detection_confidence: 0.75
    typical_files: ["*Adapter.ts", "*Wrapper.ts"]
    primary_signals: ["wraps incompatible interface", "delegates to adaptee", "converts interface"]
    anti_patterns: ["two-way adapters", "adapter chains"]
    related: [bridge, decorator, proxy]
    common_use_cases: ["third-party library integration", "legacy code integration"]

  bridge:
    difficulty: 3
    use_frequency: low
    detection_confidence: 0.60
    typical_files: ["*Bridge.ts", "*Abstraction.ts", "*Implementation.ts"]
    primary_signals: ["abstraction has implementation reference", "two hierarchies", "runtime binding"]
    anti_patterns: ["over-engineering simple scenarios"]
    related: [adapter, strategy]

  composite:
    difficulty: 2
    use_frequency: medium
    detection_confidence: 0.75
    typical_files: ["*Component.ts", "*Composite.ts", "*Leaf.ts"]
    primary_signals: ["tree structure", "uniform interface", "recursive composition", "children collection"]
    anti_patterns: ["incorrect child management", "violating uniformity"]
    related: [decorator, iterator]
    common_use_cases: ["UI component trees", "file systems", "organization structures"]

  decorator:
    difficulty: 2
    use_frequency: high
    detection_confidence: 0.70
    typical_files: ["*Decorator.ts", "*Wrapper.ts"]
    primary_signals: ["wraps same interface", "adds behavior", "delegates to wrapped", "stackable"]
    anti_patterns: ["decorator explosion", "order dependency"]
    related: [adapter, composite, proxy]
    stack_native:
      react: "Higher-Order Components (HOC)"
      angular: "Directives"
      nestjs: "Interceptors"
      typescript: "Decorators (@)"

  facade:
    difficulty: 1
    use_frequency: high
    detection_confidence: 0.80
    typical_files: ["*Facade.ts", "*API.ts", "*Interface.ts"]
    primary_signals: ["simple interface to complex subsystem", "delegates to multiple classes"]
    anti_patterns: ["god facade", "leaky abstraction"]
    related: [adapter, mediator]
    common_use_cases: ["API clients", "library wrappers", "subsystem interfaces"]

  flyweight:
    difficulty: 3
    use_frequency: low
    detection_confidence: 0.65
    typical_files: ["*Flyweight.ts", "*Factory.ts"]
    primary_signals: ["shared state", "intrinsic vs extrinsic state", "large number of objects", "factory for sharing"]
    anti_patterns: ["premature optimization", "incorrect state separation"]
    related: [singleton, factory-method]

  proxy:
    difficulty: 2
    use_frequency: medium
    detection_confidence: 0.75
    typical_files: ["*Proxy.ts"]
    primary_signals: ["same interface as real subject", "controls access", "lazy initialization", "logging/caching"]
    anti_patterns: ["proxy chains", "performance overhead"]
    related: [adapter, decorator]
    common_use_cases: ["lazy loading", "access control", "caching", "logging"]
    stack_native:
      javascript: "Proxy object"

  # Behavioral Patterns
  chain-of-responsibility:
    difficulty: 2
    use_frequency: medium
    detection_confidence: 0.70
    typical_files: ["*Handler.ts", "*Middleware.ts"]
    primary_signals: ["handler interface", "next handler reference", "handles or passes", "linked list structure"]
    anti_patterns: ["unhandled requests", "broken chains"]
    related: [command, decorator]
    stack_native:
      express: "Middleware chain (app.use)"
      nestjs: "Guards, Interceptors, Pipes"

  command:
    difficulty: 2
    use_frequency: medium
    detection_confidence: 0.75
    typical_files: ["*Command.ts", "*Action.ts"]
    primary_signals: ["execute() method", "encapsulates request", "receiver reference", "undo/redo support"]
    anti_patterns: ["command explosion", "complex commands"]
    related: [memento, chain-of-responsibility]
    stack_native:
      redux: "Action creators"
      vuex: "Mutations"

  iterator:
    difficulty: 2
    use_frequency: medium
    detection_confidence: 0.80
    typical_files: ["*Iterator.ts"]
    primary_signals: ["next() method", "hasNext()/done", "current element access", "sequential traversal"]
    anti_patterns: ["modification during iteration"]
    related: [composite, visitor]
    stack_native:
      javascript: "Iterators and generators (Symbol.iterator)"
      typescript: "Iterable<T> interface"

  mediator:
    difficulty: 3
    use_frequency: medium
    detection_confidence: 0.65
    typical_files: ["*Mediator.ts", "*Controller.ts"]
    primary_signals: ["centralized communication", "colleagues reference mediator", "loose coupling"]
    anti_patterns: ["god mediator", "tight coupling to mediator"]
    related: [facade, observer]
    stack_native:
      react: "Context API"
      angular: "Services with dependency injection"

  memento:
    difficulty: 3
    use_frequency: low
    detection_confidence: 0.60
    typical_files: ["*Memento.ts", "*Snapshot.ts", "*Caretaker.ts"]
    primary_signals: ["save state", "restore state", "encapsulated snapshot", "caretaker manages history"]
    anti_patterns: ["large state snapshots", "exposing internals"]
    related: [command]
    common_use_cases: ["undo/redo", "transaction rollback", "state history"]

  observer:
    difficulty: 2
    use_frequency: very-high
    detection_confidence: 0.85
    typical_files: ["*Observer.ts", "*Subject.ts", "*Publisher.ts", "*Subscriber.ts"]
    primary_signals: ["subscribe/unsubscribe", "notify/emit", "observers list", "one-to-many dependency"]
    anti_patterns: ["memory leaks", "notification storms", "observer order dependency"]
    related: [mediator, singleton]
    stack_native:
      javascript: "EventEmitter, EventTarget"
      react: "useState, useEffect, Context"
      angular: "RxJS Observables"
      rxjs: "Subject, BehaviorSubject, ReplaySubject"
      vue: "ref(), reactive(), watch()"

  state:
    difficulty: 2
    use_frequency: medium
    detection_confidence: 0.70
    typical_files: ["*State.ts", "*Context.ts"]
    primary_signals: ["state interface", "context holds state", "state transitions", "behavior varies by state"]
    anti_patterns: ["state explosion", "complex transitions"]
    related: [strategy, flyweight]
    stack_native:
      react: "useState, useReducer"
      redux: "Reducers"
      xstate: "State machines"

  strategy:
    difficulty: 1
    use_frequency: high
    detection_confidence: 0.80
    typical_files: ["*Strategy.ts", "*Policy.ts"]
    primary_signals: ["strategy interface", "context has strategy reference", "interchangeable algorithms"]
    anti_patterns: ["strategy explosion", "client awareness of strategies"]
    related: [state, bridge, template-method]
    stack_native:
      react: "Custom hooks"
      vue: "Composables"

  template-method:
    difficulty: 2
    use_frequency: medium
    detection_confidence: 0.75
    typical_files: ["*Template.ts", "*Abstract*.ts"]
    primary_signals: ["abstract class", "template method", "primitive operations", "hook methods"]
    anti_patterns: ["too many hooks", "subclass override complexity"]
    related: [strategy, factory-method]

  visitor:
    difficulty: 4
    use_frequency: low
    detection_confidence: 0.60
    typical_files: ["*Visitor.ts"]
    primary_signals: ["visit* methods", "double dispatch", "element accepts visitor", "operations on object structure"]
    anti_patterns: ["adding new element types", "circular dependencies"]
    related: [composite, iterator]

  interpreter:
    difficulty: 4
    use_frequency: very-low
    detection_confidence: 0.55
    typical_files: ["*Interpreter.ts", "*Expression.ts"]
    primary_signals: ["grammar rules", "interpret() method", "abstract syntax tree", "terminal/non-terminal expressions"]
    anti_patterns: ["complex grammars", "performance issues"]
    related: [composite, visitor]
    common_use_cases: ["DSLs", "query languages", "expression evaluators"]

# Detection difficulty levels
difficulty_levels:
  1: "Easy - Clear structural markers and naming conventions"
  2: "Medium - Requires pattern knowledge to distinguish from similar patterns"
  3: "Hard - Subtle structural differences, context-dependent"
  4: "Very Hard - Requires deep analysis of intent and relationships"

# Usage frequency in modern codebases
frequency_levels:
  very-high: "Ubiquitous in modern frameworks"
  high: "Common in most projects"
  medium: "Occasional use, specific scenarios"
  low: "Rare, specialized use cases"
  very-low: "Academic or niche applications"

# Confidence score interpretation
confidence_interpretation:
  0.85-1.0: "High confidence - Multiple strong signals, unlikely false positive"
  0.70-0.84: "Medium-high - Clear signals, some ambiguity possible"
  0.55-0.69: "Medium - Requires manual validation"
  0.40-0.54: "Low - Weak signals, high false positive risk"
  0.0-0.39: "Very low - Naming convention only, not reliable"

```

### reference/creational.md

```markdown
---
title: "Creational Design Patterns"
description: "Reference for Singleton, Factory, Builder, Prototype and other object creation patterns"
tags: [reference, design-patterns, architecture]
---

# Creational Design Patterns

Patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation.

## Singleton

### Definition
Ensures a class has only one instance and provides a global point of access to it.

### When to Use
- [x] Exactly one instance of a class is needed (configuration, logging, database connection)
- [x] Controlled access to a single object is required
- [x] The instance should be extensible by subclassing

**Warning**: Often overused. Consider dependency injection or context-based alternatives first.

### TypeScript Signature
```typescript
class Singleton {
  private static instance: Singleton;
  private constructor() {
    // Private constructor prevents instantiation
  }

  public static getInstance(): Singleton {
    if (!Singleton.instance) {
      Singleton.instance = new Singleton();
    }
    return Singleton.instance;
  }

  public someMethod(): void {
    // Business logic
  }
}

// Usage
const instance = Singleton.getInstance();
```

### Stack-Native Alternatives

**React**:
```typescript
// Instead of Singleton, use Context
const ConfigContext = createContext<Config>(defaultConfig);

export const ConfigProvider = ({ children }: Props) => {
  const [config] = useState(() => loadConfig());
  return <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>;
};
```

**Angular**:
```typescript
// Injectable service (singleton by default)
@Injectable({ providedIn: 'root' })
export class ConfigService {
  // Automatically singleton via DI
}
```

**NestJS**:
```typescript
@Injectable() // Default scope is SINGLETON
export class AppService {}
```

### Detection Markers
- `private constructor`
- `static getInstance()` method
- `private static instance` field
- Lazy initialization check: `if (!instance)`

### Code Smells It Fixes
- **Global state access**: Provides controlled access instead of scattered global variables
- **Multiple instances of shared resource**: Ensures single database connection, config object, etc.

### Common Mistakes
- **Hard to test**: Static methods and global state make unit testing difficult
  - *Solution*: Use dependency injection instead, or provide `resetInstance()` for tests
- **Thread-safety issues**: (Less relevant in JavaScript's single-threaded model, but important for Node.js workers)
- **Hidden dependencies**: Classes using `getInstance()` have hidden coupling
- **Violates Single Responsibility**: Often manages both instance creation and business logic

### Evaluation Criteria
- **Testability**: 3/10 (hard to mock, global state)
- **Thread-safety**: 7/10 (less critical in JS)
- **Extensibility**: 5/10 (subclassing is complex)

---

## Factory Method

### Definition
Defines an interface for creating an object, but lets subclasses decide which class to instantiate.

### When to Use
- [x] Class cannot anticipate the type of objects it needs to create
- [x] Class wants its subclasses to specify the objects it creates
- [x] Centralize object creation logic to avoid duplication
- [x] Need to decouple object creation from usage

### TypeScript Signature
```typescript
// Product interface
interface Product {
  operation(): string;
}

// Concrete products
class ConcreteProductA implements Product {
  operation(): string {
    return 'Product A';
  }
}

class ConcreteProductB implements Product {
  operation(): string {
    return 'Product B';
  }
}

// Creator (Factory)
abstract class Creator {
  // Factory method
  abstract createProduct(): Product;

  // Business logic using the product
  someOperation(): string {
    const product = this.createProduct();
    return `Creator: ${product.operation()}`;
  }
}

// Concrete creators
class CreatorA extends Creator {
  createProduct(): Product {
    return new ConcreteProductA();
  }
}

class CreatorB extends Creator {
  createProduct(): Product {
    return new ConcreteProductB();
  }
}

// Usage
const creator: Creator = new CreatorA();
console.log(creator.someOperation());
```

### Modern TypeScript Alternative
```typescript
// Simpler approach without inheritance
type ProductType = 'A' | 'B';

function createProduct(type: ProductType): Product {
  switch (type) {
    case 'A': return new ConcreteProductA();
    case 'B': return new ConcreteProductB();
  }
}
```

### Detection Markers
- Method named `create*()` returning interface/abstract class
- `abstract createProduct()` in base class
- Subclasses override factory method
- `switch` or `if-else` on type/kind parameter

### Code Smells It Fixes
- **Tight coupling to concrete classes**: Client code depends on interface, not implementation
- **Duplication of instantiation logic**: Centralized in factory method
- **Switch statements scattered**: Consolidated in one place

### Common Mistakes
- **Simple Factory confusion**: Factory Method uses inheritance; Simple Factory uses composition
- **Too many parameters**: Should create objects with default configuration
- **Forgetting to make factory method abstract**: Defeats the purpose of subclass specialization

### Evaluation Criteria
- **Testability**: 8/10 (easy to mock products)
- **Flexibility**: 9/10 (new products don't modify existing code)
- **Complexity**: 6/10 (adds inheritance hierarchy)

---

## Abstract Factory

### Definition
Provides an interface for creating families of related or dependent objects without specifying their concrete classes.

### When to Use
- [x] System should be independent of how its products are created
- [x] System should be configured with one of multiple families of products
- [x] Family of related product objects must be used together
- [x] You want to provide a library of products and reveal only interfaces

### TypeScript Signature
```typescript
// Abstract products
interface AbstractProductA {
  usefulFunctionA(): string;
}

interface AbstractProductB {
  usefulFunctionB(): string;
  anotherFunctionB(collaborator: AbstractProductA): string;
}

// Concrete products - Family 1
class ConcreteProductA1 implements AbstractProductA {
  usefulFunctionA(): string {
    return 'Product A1';
  }
}

class ConcreteProductB1 implements AbstractProductB {
  usefulFunctionB(): string {
    return 'Product B1';
  }

  anotherFunctionB(collaborator: AbstractProductA): string {
    return `B1 collaborating with ${collaborator.usefulFunctionA()}`;
  }
}

// Concrete products - Family 2
class ConcreteProductA2 implements AbstractProductA {
  usefulFunctionA(): string {
    return 'Product A2';
  }
}

class ConcreteProductB2 implements AbstractProductB {
  usefulFunctionB(): string {
    return 'Product B2';
  }

  anotherFunctionB(collaborator: AbstractProductA): string {
    return `B2 collaborating with ${collaborator.usefulFunctionA()}`;
  }
}

// Abstract factory
interface AbstractFactory {
  createProductA(): AbstractProductA;
  createProductB(): AbstractProductB;
}

// Concrete factories
class ConcreteFactory1 implements AbstractFactory {
  createProductA(): AbstractProductA {
    return new ConcreteProductA1();
  }

  createProductB(): AbstractProductB {
    return new ConcreteProductB1();
  }
}

class ConcreteFactory2 implements AbstractFactory {
  createProductA(): AbstractProductA {
    return new ConcreteProductA2();
  }

  createProductB(): AbstractProductB {
    return new ConcreteProductB2();
  }
}

// Client code
function clientCode(factory: AbstractFactory) {
  const productA = factory.createProductA();
  const productB = factory.createProductB();

  console.log(productB.anotherFunctionB(productA));
}

// Usage
clientCode(new ConcreteFactory1());
clientCode(new ConcreteFactory2());
```

### Detection Markers
- Multiple `create*()` methods in factory interface
- Families of related products (e.g., Button + Checkbox for Windows/Mac)
- Factory implementations return different product families
- Interface with 2+ factory methods

### Code Smells It Fixes
- **Inconsistent product families**: Ensures compatible products are created together (Windows Button + Windows Checkbox, not mixed)
- **Scattered creation logic**: Centralizes creation of related objects

### Common Mistakes
- **Over-engineering**: Often too complex for simple scenarios; Factory Method may suffice
- **Rigid product families**: Adding new product types requires changing all factories
- **Confusion with Factory Method**: Abstract Factory creates families; Factory Method creates one product type

### Evaluation Criteria
- **Testability**: 8/10 (factories are easily mocked)
- **Consistency**: 10/10 (guarantees compatible products)
- **Complexity**: 4/10 (high complexity, many classes)

---

## Builder

### Definition
Separates the construction of a complex object from its representation, allowing step-by-step construction.

### When to Use
- [x] Object has many optional parameters (>4)
- [x] Construction process should allow different representations
- [x] Need to construct complex objects step-by-step
- [x] Want to avoid "telescoping constructor" anti-pattern

### TypeScript Signature
```typescript
// Product
class House {
  public walls: string = '';
  public doors: number = 0;
  public windows: number = 0;
  public roof: string = '';
  public garage: boolean = false;
  public pool: boolean = false;

  public describe(): string {
    return `House with ${this.walls} walls, ${this.doors} doors, ${this.windows} windows, ${this.roof} roof, garage: ${this.garage}, pool: ${this.pool}`;
  }
}

// Builder
class HouseBuilder {
  private house: House;

  constructor() {
    this.house = new House();
  }

  public setWalls(walls: string): this {
    this.house.walls = walls;
    return this;
  }

  public setDoors(doors: number): this {
    this.house.doors = doors;
    return this;
  }

  public setWindows(windows: number): this {
    this.house.windows = windows;
    return this;
  }

  public setRoof(roof: string): this {
    this.house.roof = roof;
    return this;
  }

  public addGarage(): this {
    this.house.garage = true;
    return this;
  }

  public addPool(): this {
    this.house.pool = true;
    return this;
  }

  public build(): House {
    const result = this.house;
    this.house = new House(); // Reset for next build
    return result;
  }
}

// Usage
const house = new HouseBuilder()
  .setWalls('brick')
  .setDoors(2)
  .setWindows(6)
  .setRoof('tile')
  .addGarage()
  .build();
```

### Modern TypeScript Alternative (Type-Safe Builder)
```typescript
// Progressive type safety: each step unlocks the next
type HouseBuilderState<
  TWalls extends boolean = false,
  TRoof extends boolean = false
> = {
  setWalls: TWalls extends true ? never : (walls: string) => HouseBuilderState<true, TRoof>;
  setRoof: TRoof extends true ? never : (roof: string) => HouseBuilderState<TWalls, true>;
  build: TWalls extends true ? (TRoof extends true ? () => House : never) : never;
};
```

### Detection Markers
- Method chaining (returns `this` or builder type)
- `build()` method returning final product
- `with*()` or `set*()` methods
- Optional fields being set incrementally

### Code Smells It Fixes
- **Telescoping constructor**: Constructor with many parameters
  ```typescript
  // Bad
  new House(walls, doors, windows, roof, garage, pool, garden, basement, ...);

  // Good with Builder
  new HouseBuilder().setWalls('brick').setRoof('tile').build();
  ```
- **Unclear parameter order**: Named methods make intent clear
- **Optional parameters complexity**: Builder handles optional features elegantly

### Common Mistakes
- **Mutable builder**: Reusing builder can lead to unexpected state
  - *Solution*: Reset internal state after `build()`
- **Incomplete builder**: Not validating required fields in `build()`
  - *Solution*: Use TypeScript types to enforce required steps
- **Too simple for the pattern**: If <4 parameters, constructor or object literal may be simpler

### Evaluation Criteria
- **Testability**: 9/10 (easy to create test fixtures)
- **Readability**: 10/10 (fluent interface is self-documenting)
- **Complexity**: 7/10 (adds builder class)

---

## Prototype

### Definition
Creates new objects by copying an existing object (prototype) rather than creating from scratch.

### When to Use
- [x] Object creation is expensive (complex initialization, database queries)
- [x] Need to avoid subclassing just to change initialization
- [x] System should be independent of how products are created
- [x] Classes to instantiate are specified at runtime

### TypeScript Signature
```typescript
// Prototype interface
interface Prototype {
  clone(): Prototype;
}

// Concrete prototype
class ConcretePrototype implements Prototype {
  public field: number;
  public complexObject: { data: string };

  constructor(field: number, complexObject: { data: string }) {
    this.field = field;
    this.complexObject = complexObject;
  }

  // Shallow clone
  public clone(): ConcretePrototype {
    return Object.create(this);
  }

  // Deep clone
  public deepClone(): ConcretePrototype {
    return new ConcretePrototype(
      this.field,
      { data: this.complexObject.data } // Clone nested objects
    );
  }
}

// Usage
const original = new ConcretePrototype(42, { data: 'important' });
const shallowCopy = original.clone();
const deepCopy = original.deepClone();

// Shallow copy shares nested objects
shallowCopy.complexObject.data = 'modified';
console.log(original.complexObject.data); // 'modified' (!)

// Deep copy is independent
deepCopy.field = 99;
console.log(original.field); // 42 (unchanged)
```

### Modern JavaScript Alternatives
```typescript
// Spread operator (shallow)
const copy1 = { ...original };

// Object.assign (shallow)
const copy2 = Object.assign({}, original);

// structuredClone (deep, modern browsers/Node 17+)
const copy3 = structuredClone(original);

// JSON (deep, but limited: no functions, undefined, etc.)
const copy4 = JSON.parse(JSON.stringify(original));
```

### Detection Markers
- `clone()` method
- `Object.create()`
- `structuredClone()`
- `JSON.parse(JSON.stringify())` pattern
- Spread operator `{ ...obj }`

### Code Smells It Fixes
- **Expensive initialization**: Clone instead of re-initializing
- **Complex object graphs**: Cloning preserves relationships
- **Runtime type specification**: Clone prototype instead of hardcoding types

### Common Mistakes
- **Shallow vs Deep clone confusion**: Shallow clone shares nested objects
  ```typescript
  // Dangerous if nested objects are modified
  const shallow = { ...original };
  ```
- **Circular references**: `JSON.stringify` fails on circular references
  - *Solution*: Use `structuredClone()` or custom clone logic
- **Cloning methods/functions**: Some approaches lose methods
  ```typescript
  JSON.parse(JSON.stringify(obj)); // Loses all methods!
  ```
- **Not cloning private state**: Ensure all necessary state is copied

### Evaluation Criteria
- **Performance**: 9/10 (faster than re-initialization)
- **Simplicity**: 7/10 (shallow vs deep cloning is tricky)
- **Reliability**: 6/10 (easy to get wrong with nested objects)

---

## Summary Table

| Pattern | Complexity | Use Frequency | Main Benefit |
|---------|------------|---------------|--------------|
| Singleton | Low | High | Global access control |
| Factory Method | Medium | High | Decouples creation from usage |
| Abstract Factory | High | Medium | Consistent product families |
| Builder | Medium | High | Fluent construction of complex objects |
| Prototype | Low | Low | Efficient cloning |

## Best Practices

1. **Prefer composition over inheritance**: Factory and Builder often better than Singleton
2. **Use stack-native alternatives**: React Context > Singleton, DI > getInstance()
3. **TypeScript leverage**: Use generics and type constraints for type-safe builders
4. **Test-friendly design**: Avoid Singleton; use dependency injection
5. **Simplicity first**: Don't use Abstract Factory when Factory Method suffices

## References

- *Design Patterns: Elements of Reusable Object-Oriented Software* (Gang of Four)
- *Effective TypeScript* by Dan Vanderkam
- [Refactoring Guru: Creational Patterns](https://refactoring.guru/design-patterns/creational-patterns)

```

### reference/structural.md

```markdown
---
title: "Structural Design Patterns"
description: "Reference for Adapter, Decorator, Facade, Proxy and other composition patterns"
tags: [reference, design-patterns, architecture]
---

# Structural Design Patterns

Patterns that deal with object composition and relationships between entities, providing ways to assemble objects and classes into larger structures.

## Adapter

### Definition
Converts the interface of a class into another interface clients expect, allowing incompatible interfaces to work together.

### When to Use
- [x] Want to use an existing class with an incompatible interface
- [x] Need to integrate third-party libraries with different interfaces
- [x] Want to create a reusable class that cooperates with unrelated classes
- [x] Legacy code must work with new systems

### TypeScript Signature
```typescript
// Target interface (what client expects)
interface Target {
  request(): string;
}

// Adaptee (existing incompatible class)
class Adaptee {
  specificRequest(): string {
    return '.eetpadA eht fo roivaheb laicepS';
  }
}

// Adapter (makes Adaptee compatible with Target)
class Adapter implements Target {
  private adaptee: Adaptee;

  constructor(adaptee: Adaptee) {
    this.adaptee = adaptee;
  }

  public request(): string {
    const result = this.adaptee.specificRequest().split('').reverse().join('');
    return `Adapter: ${result}`;
  }
}

// Client code
function clientCode(target: Target) {
  console.log(target.request());
}

// Usage
const adaptee = new Adaptee();
const adapter = new Adapter(adaptee);
clientCode(adapter);
```

### Real-World Example: Third-Party Library Integration
```typescript
// Third-party library (can't modify)
class XMLDataProvider {
  getXMLData(): string {
    return '<data><item>1</item></data>';
  }
}

// Your application expects JSON
interface JSONDataProvider {
  getJSONData(): object;
}

// Adapter
class XMLToJSONAdapter implements JSONDataProvider {
  constructor(private xmlProvider: XMLDataProvider) {}

  getJSONData(): object {
    const xml = this.xmlProvider.getXMLData();
    // Convert XML to JSON (simplified)
    return { data: { item: '1' } };
  }
}

// Usage
const xmlProvider = new XMLDataProvider();
const adapter = new XMLToJSONAdapter(xmlProvider);
const data = adapter.getJSONData();
```

### Detection Markers
- Class implements target interface
- Holds reference to adaptee
- Delegates to adaptee with interface conversion
- Names like `*Adapter`, `*Wrapper`

### Code Smells It Fixes
- **Incompatible interfaces**: Makes legacy or third-party code compatible
- **Interface proliferation**: Single adapter vs modifying multiple client calls

### Common Mistakes
- **Two-way adapters**: Bidirectional conversion is complex; create two adapters
- **Adapter chains**: Multiple adapters in sequence indicate design issues
- **Overusing for new code**: Design compatible interfaces from the start

---

## Bridge

### Definition
Decouples an abstraction from its implementation so the two can vary independently.

### When to Use
- [x] Want to avoid permanent binding between abstraction and implementation
- [x] Both abstractions and implementations should be extensible by subclassing
- [x] Changes in implementation shouldn't affect clients
- [x] Want to share implementation among multiple objects (Flyweight-like)

### TypeScript Signature
```typescript
// Implementation interface
interface Implementation {
  operationImpl(): string;
}

// Concrete implementations
class ConcreteImplementationA implements Implementation {
  operationImpl(): string {
    return 'ConcreteImplementationA';
  }
}

class ConcreteImplementationB implements Implementation {
  operationImpl(): string {
    return 'ConcreteImplementationB';
  }
}

// Abstraction
class Abstraction {
  constructor(protected implementation: Implementation) {}

  public operation(): string {
    return `Abstraction: ${this.implementation.operationImpl()}`;
  }
}

// Refined abstraction
class ExtendedAbstraction extends Abstraction {
  public operation(): string {
    return `ExtendedAbstraction: ${this.implementation.operationImpl()}`;
  }
}

// Usage
const implA = new ConcreteImplementationA();
const abstraction1 = new Abstraction(implA);
console.log(abstraction1.operation());

const implB = new ConcreteImplementationB();
const abstraction2 = new ExtendedAbstraction(implB);
console.log(abstraction2.operation());
```

### Real-World Example: UI Components with Multiple Renderers
```typescript
// Implementation: Renderers
interface Renderer {
  renderCircle(radius: number): string;
  renderSquare(side: number): string;
}

class VectorRenderer implements Renderer {
  renderCircle(radius: number): string {
    return `Drawing circle (vector) with radius ${radius}`;
  }
  renderSquare(side: number): string {
    return `Drawing square (vector) with side ${side}`;
  }
}

class RasterRenderer implements Renderer {
  renderCircle(radius: number): string {
    return `Drawing circle (pixels) with radius ${radius}`;
  }
  renderSquare(side: number): string {
    return `Drawing square (pixels) with side ${side}`;
  }
}

// Abstraction: Shapes
abstract class Shape {
  constructor(protected renderer: Renderer) {}
  abstract draw(): string;
}

class Circle extends Shape {
  constructor(renderer: Renderer, private radius: number) {
    super(renderer);
  }
  draw(): string {
    return this.renderer.renderCircle(this.radius);
  }
}

class Square extends Shape {
  constructor(renderer: Renderer, private side: number) {
    super(renderer);
  }
  draw(): string {
    return this.renderer.renderSquare(this.side);
  }
}

// Usage: Can mix any shape with any renderer
const vectorCircle = new Circle(new VectorRenderer(), 5);
const rasterSquare = new Square(new RasterRenderer(), 10);
```

### Detection Markers
- Abstraction holds reference to implementation interface
- Constructor injects implementation
- Two parallel hierarchies (abstraction and implementation)

### Common Mistakes
- **Confusion with Adapter**: Bridge is design-time; Adapter is runtime fix
- **Over-engineering simple scenarios**: Use only when both hierarchies need to vary

---

## Composite

### Definition
Composes objects into tree structures to represent part-whole hierarchies, letting clients treat individual objects and compositions uniformly.

### When to Use
- [x] Want to represent part-whole hierarchies of objects
- [x] Want clients to ignore difference between compositions and individual objects
- [x] Tree structures are natural for the domain (file systems, UI components, org charts)

### TypeScript Signature
```typescript
// Component interface
interface Component {
  operation(): string;
  add?(component: Component): void;
  remove?(component: Component): void;
  getChild?(index: number): Component;
}

// Leaf (no children)
class Leaf implements Component {
  constructor(private name: string) {}

  operation(): string {
    return this.name;
  }
}

// Composite (has children)
class Composite implements Component {
  private children: Component[] = [];

  constructor(private name: string) {}

  add(component: Component): void {
    this.children.push(component);
  }

  remove(component: Component): void {
    const index = this.children.indexOf(component);
    if (index !== -1) {
      this.children.splice(index, 1);
    }
  }

  getChild(index: number): Component {
    return this.children[index];
  }

  operation(): string {
    const results = this.children.map(child => child.operation());
    return `${this.name}(${results.join(', ')})`;
  }
}

// Usage
const tree = new Composite('root');
const branch1 = new Composite('branch1');
branch1.add(new Leaf('leaf1'));
branch1.add(new Leaf('leaf2'));

const branch2 = new Composite('branch2');
branch2.add(new Leaf('leaf3'));

tree.add(branch1);
tree.add(branch2);
tree.add(new Leaf('leaf4'));

console.log(tree.operation());
// Output: root(branch1(leaf1, leaf2), branch2(leaf3), leaf4)
```

### Real-World Example: File System
```typescript
interface FileSystemComponent {
  getName(): string;
  getSize(): number;
  print(indent: string): void;
}

class File implements FileSystemComponent {
  constructor(private name: string, private size: number) {}

  getName(): string {
    return this.name;
  }

  getSize(): number {
    return this.size;
  }

  print(indent: string): void {
    console.log(`${indent}📄 ${this.name} (${this.size} bytes)`);
  }
}

class Directory implements FileSystemComponent {
  private children: FileSystemComponent[] = [];

  constructor(private name: string) {}

  add(component: FileSystemComponent): void {
    this.children.push(component);
  }

  getName(): string {
    return this.name;
  }

  getSize(): number {
    return this.children.reduce((sum, child) => sum + child.getSize(), 0);
  }

  print(indent: string): void {
    console.log(`${indent}📁 ${this.name} (${this.getSize()} bytes)`);
    this.children.forEach(child => child.print(indent + '  '));
  }
}

// Usage
const root = new Directory('root');
const home = new Directory('home');
home.add(new File('photo.jpg', 2048));
home.add(new File('document.pdf', 4096));

const work = new Directory('work');
work.add(new File('report.docx', 8192));

root.add(home);
root.add(work);
root.print('');
```

### Detection Markers
- Tree structure with uniform interface
- Collection of children components
- `add()`, `remove()`, `getChild()` methods
- Recursive operation calls

### Code Smells It Fixes
- **Type checking for composition vs leaf**: Uniform interface eliminates `instanceof` checks
- **Different handling for parts vs wholes**: Clients treat both uniformly

### Common Mistakes
- **Violating uniformity**: Leaf and Composite should have same interface
- **Incorrect child management**: Not handling removal properly
- **Deep recursion**: Can cause stack overflow on very deep trees

---

## Decorator

### Definition
Attaches additional responsibilities to an object dynamically, providing a flexible alternative to subclassing for extending functionality.

### When to Use
- [x] Need to add responsibilities to objects dynamically and transparently
- [x] Responsibilities can be withdrawn
- [x] Extension by subclassing is impractical (many possible combinations)
- [x] Want to add features incrementally

### TypeScript Signature
```typescript
// Component interface
interface Component {
  operation(): string;
}

// Concrete component
class ConcreteComponent implements Component {
  operation(): string {
    return 'ConcreteComponent';
  }
}

// Base decorator
abstract class Decorator implements Component {
  constructor(protected component: Component) {}

  operation(): string {
    return this.component.operation();
  }
}

// Concrete decorators
class DecoratorA extends Decorator {
  operation(): string {
    return `DecoratorA(${super.operation()})`;
  }
}

class DecoratorB extends Decorator {
  operation(): string {
    return `DecoratorB(${super.operation()})`;
  }
}

// Usage: Stack decorators
const simple = new ConcreteComponent();
const decorated1 = new DecoratorA(simple);
const decorated2 = new DecoratorB(decorated1);
console.log(decorated2.operation());
// Output: DecoratorB(DecoratorA(ConcreteComponent))
```

### Stack-Native Alternatives

**React - Higher-Order Components**:
```typescript
// HOC decorator
function withAuth<P extends object>(
  Component: React.ComponentType<P>
): React.ComponentType<P> {
  return (props: P) => {
    const { user } = useAuth();
    if (!user) return <Redirect to="/login" />;
    return <Component {...props} />;
  };
}

// Usage: Stack decorators
const AuthenticatedProfile = withAuth(Profile);
const AuthenticatedAdminProfile = withLogging(withAuth(Profile));
```

**NestJS - Interceptors**:
```typescript
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');
    return next.handle().pipe(
      tap(() => console.log('After...'))
    );
  }
}

// Apply decorator
@UseInterceptors(LoggingInterceptor)
@Controller('users')
export class UsersController {}
```

### Detection Markers
- Implements same interface as wrapped object
- Holds reference to wrapped object
- Delegates to wrapped, adding behavior
- Can be stacked

### Code Smells It Fixes
- **Class explosion**: Avoid creating subclass for every feature combination
- **Rigid feature addition**: Add/remove features dynamically

### Common Mistakes
- **Order dependency**: DecoratorA(DecoratorB(x)) ≠ DecoratorB(DecoratorA(x))
- **Decorator explosion**: Too many small decorators can be hard to manage
- **Breaking interface**: Decorator must maintain interface contract

---

## Facade

### Definition
Provides a unified interface to a set of interfaces in a subsystem, making the subsystem easier to use.

### When to Use
- [x] Want to provide a simple interface to a complex subsystem
- [x] Many dependencies exist between clients and implementation classes
- [x] Want to layer subsystems
- [x] Need to decouple subsystem from clients

### TypeScript Signature
```typescript
// Complex subsystem classes
class SubsystemA {
  operationA(): string {
    return 'SubsystemA';
  }
}

class SubsystemB {
  operationB(): string {
    return 'SubsystemB';
  }
}

class SubsystemC {
  operationC(): string {
    return 'SubsystemC';
  }
}

// Facade
class Facade {
  private subsystemA: SubsystemA;
  private subsystemB: SubsystemB;
  private subsystemC: SubsystemC;

  constructor() {
    this.subsystemA = new SubsystemA();
    this.subsystemB = new SubsystemB();
    this.subsystemC = new SubsystemC();
  }

  // Simplified interface
  public simpleOperation(): string {
    const resultA = this.subsystemA.operationA();
    const resultB = this.subsystemB.operationB();
    const resultC = this.subsystemC.operationC();
    return `Facade coordinates: ${resultA}, ${resultB}, ${resultC}`;
  }
}

// Client code
const facade = new Facade();
console.log(facade.simpleOperation());
// Instead of:
// const a = new SubsystemA(); const b = new SubsystemB(); const c = new SubsystemC();
// a.operationA(); b.operationB(); c.operationC();
```

### Real-World Example: Payment Processing
```typescript
// Complex subsystems
class PaymentValidator {
  validate(amount: number, card: string): boolean {
    // Complex validation logic
    return amount > 0 && card.length === 16;
  }
}

class PaymentGateway {
  charge(amount: number, card: string): string {
    return `Charged $${amount} to ${card}`;
  }
}

class NotificationService {
  sendReceipt(email: string, transactionId: string): void {
    console.log(`Receipt sent to ${email}: ${transactionId}`);
  }
}

class TransactionLogger {
  log(transaction: string): void {
    console.log(`Logged: ${transaction}`);
  }
}

// Facade
class PaymentFacade {
  private validator = new PaymentValidator();
  private gateway = new PaymentGateway();
  private notifications = new NotificationService();
  private logger = new TransactionLogger();

  processPayment(amount: number, card: string, email: string): boolean {
    // Simplified interface for complex process
    if (!this.validator.validate(amount, card)) {
      return false;
    }

    const result = this.gateway.charge(amount, card);
    this.logger.log(result);
    this.notifications.sendReceipt(email, result);
    return true;
  }
}

// Client code (simple!)
const payment = new PaymentFacade();
payment.processPayment(100, '1234567890123456', '[email protected]');
```

### Detection Markers
- Class with multiple subsystem dependencies
- Simple public methods coordinating subsystems
- Named `*Facade`, `*API`, `*Service`

### Code Smells It Fixes
- **Complex subsystem usage**: Clients don't need to know subsystem details
- **Tight coupling**: Clients depend on facade, not many classes

### Common Mistakes
- **God Facade**: Facade does too much; should coordinate, not contain logic
- **Leaky abstraction**: Exposing subsystem details defeats the purpose

---

## Flyweight

### Definition
Uses sharing to support large numbers of fine-grained objects efficiently by storing shared state externally.

### When to Use
- [x] Application uses large number of objects
- [x] Storage cost is high due to object quantity
- [x] Most object state can be made extrinsic (externalized)
- [x] Many groups of objects may be replaced by relatively few shared objects

### TypeScript Signature
```typescript
// Flyweight
class Flyweight {
  constructor(private sharedState: string) {}

  operation(uniqueState: string): void {
    console.log(`Flyweight: Shared (${this.sharedState}) and unique (${uniqueState}) state.`);
  }
}

// Flyweight factory
class FlyweightFactory {
  private flyweights: Map<string, Flyweight> = new Map();

  constructor(initialFlyweights: string[][]) {
    for (const state of initialFlyweights) {
      this.flyweights.set(this.getKey(state), new Flyweight(state.join('_')));
    }
  }

  private getKey(state: string[]): string {
    return state.join('_');
  }

  getFlyweight(sharedState: string[]): Flyweight {
    const key = this.getKey(sharedState);

    if (!this.flyweights.has(key)) {
      console.log('Creating new flyweight');
      this.flyweights.set(key, new Flyweight(key));
    } else {
      console.log('Reusing existing flyweight');
    }

    return this.flyweights.get(key)!;
  }

  listFlyweights(): void {
    console.log(`FlyweightFactory: ${this.flyweights.size} flyweights:`);
    for (const key of this.flyweights.keys()) {
      console.log(key);
    }
  }
}

// Usage
const factory = new FlyweightFactory([
  ['Chevrolet', 'Camaro2018', 'pink'],
  ['Mercedes Benz', 'C300', 'black'],
]);

const flyweight1 = factory.getFlyweight(['Chevrolet', 'Camaro2018', 'pink']);
flyweight1.operation('license-123');

const flyweight2 = factory.getFlyweight(['Chevrolet', 'Camaro2018', 'pink']);
flyweight2.operation('license-456'); // Reuses same flyweight
```

### Real-World Example: Text Editor Characters
```typescript
// Flyweight: Character formatting (shared)
class CharacterFormat {
  constructor(
    public font: string,
    public size: number,
    public color: string
  ) {}
}

// Flyweight factory
class FormatFactory {
  private formats = new Map<string, CharacterFormat>();

  getFormat(font: string, size: number, color: string): CharacterFormat {
    const key = `${font}_${size}_${color}`;
    if (!this.formats.has(key)) {
      this.formats.set(key, new CharacterFormat(font, size, color));
    }
    return this.formats.get(key)!;
  }
}

// Character with extrinsic state
class Character {
  constructor(
    private char: string,
    private format: CharacterFormat // Shared flyweight
  ) {}

  render(position: number): string {
    return `'${this.char}' at ${position} (${this.format.font}, ${this.format.size}px, ${this.format.color})`;
  }
}

// Document
const formatFactory = new FormatFactory();
const arial12Black = formatFactory.getFormat('Arial', 12, 'black');
const arial12Red = formatFactory.getFormat('Arial', 12, 'red');

// 10,000 characters, but only 2 format objects
const characters: Character[] = [];
for (let i = 0; i < 10000; i++) {
  const format = i % 2 === 0 ? arial12Black : arial12Red;
  characters.push(new Character('A', format));
}
```

### Detection Markers
- Factory managing pool of shared objects
- Intrinsic (shared) vs extrinsic (unique) state separation
- Map/cache of flyweights

### Common Mistakes
- **Premature optimization**: Only use if memory is actually a problem
- **Incorrect state separation**: Mixing intrinsic and extrinsic state

---

## Proxy

### Definition
Provides a surrogate or placeholder for another object to control access to it.

### When to Use
- [x] Lazy initialization (virtual proxy): Create expensive object only when needed
- [x] Access control (protection proxy): Control access to original object
- [x] Local representative of remote object (remote proxy)
- [x] Logging, caching, or monitoring access

### TypeScript Signature
```typescript
// Subject interface
interface Subject {
  request(): void;
}

// Real subject
class RealSubject implements Subject {
  request(): void {
    console.log('RealSubject: Handling request');
  }
}

// Proxy
class Proxy implements Subject {
  private realSubject: RealSubject | null = null;

  request(): void {
    // Access control
    if (this.checkAccess()) {
      // Lazy initialization
      if (!this.realSubject) {
        this.realSubject = new RealSubject();
      }

      // Logging
      this.logAccess();

      // Delegate to real subject
      this.realSubject.request();
    }
  }

  private checkAccess(): boolean {
    console.log('Proxy: Checking access');
    return true;
  }

  private logAccess(): void {
    console.log('Proxy: Logging access time');
  }
}

// Usage
const proxy = new Proxy();
proxy.request();
// Output:
// Proxy: Checking access
// Proxy: Logging access time
// RealSubject: Handling request
```

### Modern JavaScript Proxy
```typescript
const target = {
  message: 'Hello',
  getValue() {
    return this.message;
  }
};

const handler = {
  get(target: any, prop: string) {
    console.log(`Accessing property: ${prop}`);
    return target[prop];
  },
  set(target: any, prop: string, value: any) {
    console.log(`Setting property: ${prop} = ${value}`);
    target[prop] = value;
    return true;
  }
};

const proxy = new Proxy(target, handler);
console.log(proxy.message); // Logs: Accessing property: message
proxy.message = 'World';     // Logs: Setting property: message = World
```

### Detection Markers
- Implements same interface as real subject
- Holds reference to real subject
- Controls access (checks, logging, caching)
- Lazy initialization of real subject

### Common Mistakes
- **Proxy chains**: Multiple proxies wrapping each other
- **Performance overhead**: Every access goes through proxy
- **Confusion with Decorator**: Proxy controls access; Decorator adds behavior

---

## Summary Table

| Pattern | Complexity | Use Frequency | Main Benefit |
|---------|------------|---------------|--------------|
| Adapter | Low | High | Interface compatibility |
| Bridge | High | Low | Decouple abstraction from implementation |
| Composite | Medium | High | Uniform tree structure handling |
| Decorator | Medium | High | Dynamic responsibility addition |
| Facade | Low | Very High | Simplified subsystem interface |
| Flyweight | High | Low | Memory optimization |
| Proxy | Medium | Medium | Controlled access |

## Best Practices

1. **Adapter vs Bridge**: Adapter fixes incompatibility; Bridge designs flexibility
2. **Decorator vs Proxy**: Decorator adds features; Proxy controls access
3. **Facade simplicity**: Should coordinate, not contain business logic
4. **Composite uniformity**: Leaf and Composite must share interface
5. **Use native Proxy**: JavaScript `Proxy` object for dynamic property access

## References

- *Design Patterns: Elements of Reusable Object-Oriented Software* (Gang of Four)
- [MDN: Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
- [Refactoring Guru: Structural Patterns](https://refactoring.guru/design-patterns/structural-patterns)

```

### reference/behavioral.md

```markdown
---
title: "Behavioral Design Patterns"
description: "Reference for Observer, Strategy, Command, Chain of Responsibility and other behavior patterns"
tags: [reference, design-patterns, architecture]
---

# Behavioral Design Patterns

Patterns concerned with algorithms and the assignment of responsibilities between objects, focusing on communication patterns.

## Chain of Responsibility

### Definition
Passes requests along a chain of handlers, where each handler decides either to process the request or pass it to the next handler.

### When to Use
- [x] More than one object may handle a request, and handler isn't known a priori
- [x] Want to issue request without specifying receiver explicitly
- [x] Set of handlers can be specified dynamically
- [x] Processing order matters

### TypeScript Signature
```typescript
interface Handler {
  setNext(handler: Handler): Handler;
  handle(request: string): string | null;
}

abstract class AbstractHandler implements Handler {
  private nextHandler: Handler | null = null;

  setNext(handler: Handler): Handler {
    this.nextHandler = handler;
    return handler; // Allows chaining: h1.setNext(h2).setNext(h3)
  }

  handle(request: string): string | null {
    if (this.nextHandler) {
      return this.nextHandler.handle(request);
    }
    return null;
  }
}

class ConcreteHandlerA extends AbstractHandler {
  handle(request: string): string | null {
    if (request === 'A') {
      return `HandlerA processed ${request}`;
    }
    return super.handle(request);
  }
}

class ConcreteHandlerB extends AbstractHandler {
  handle(request: string): string | null {
    if (request === 'B') {
      return `HandlerB processed ${request}`;
    }
    return super.handle(request);
  }
}

// Usage
const handlerA = new ConcreteHandlerA();
const handlerB = new ConcreteHandlerB();
handlerA.setNext(handlerB);

console.log(handlerA.handle('B')); // HandlerB processed B
```

### Stack-Native Alternatives

**Express Middleware**:
```typescript
app.use(authMiddleware);
app.use(loggingMiddleware);
app.use(errorMiddleware);
```

**NestJS Guards/Interceptors**:
```typescript
@UseGuards(AuthGuard, RolesGuard)
@UseInterceptors(LoggingInterceptor)
```

### Code Smells It Fixes
- **Tight coupling to request handler**: Client doesn't know which handler processes request
- **Complex conditional logic**: Each handler has simple logic

---

## Command

### Definition
Encapsulates a request as an object, letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

### When to Use
- [x] Parameterize objects with operations
- [x] Queue, specify, and execute requests at different times
- [x] Support undo/redo operations
- [x] Log changes for system crash recovery

### TypeScript Signature
```typescript
// Command interface
interface Command {
  execute(): void;
  undo?(): void;
}

// Receiver
class Light {
  turnOn(): void {
    console.log('Light is on');
  }
  turnOff(): void {
    console.log('Light is off');
  }
}

// Concrete commands
class TurnOnCommand implements Command {
  constructor(private light: Light) {}

  execute(): void {
    this.light.turnOn();
  }

  undo(): void {
    this.light.turnOff();
  }
}

class TurnOffCommand implements Command {
  constructor(private light: Light) {}

  execute(): void {
    this.light.turnOff();
  }

  undo(): void {
    this.light.turnOn();
  }
}

// Invoker
class RemoteControl {
  private history: Command[] = [];

  execute(command: Command): void {
    command.execute();
    this.history.push(command);
  }

  undo(): void {
    const command = this.history.pop();
    if (command?.undo) {
      command.undo();
    }
  }
}

// Usage
const light = new Light();
const remote = new RemoteControl();

remote.execute(new TurnOnCommand(light));  // Light is on
remote.execute(new TurnOffCommand(light)); // Light is off
remote.undo();                             // Light is on
```

### Stack-Native: Redux Actions
```typescript
const incrementAction = { type: 'INCREMENT', payload: 1 };
dispatch(incrementAction); // Command pattern
```

---

## Iterator

### Definition
Provides a way to access elements of a collection sequentially without exposing its underlying representation.

### When to Use
- [x] Need to access collection's contents without exposing internal structure
- [x] Support multiple traversals of collections
- [x] Provide uniform interface for traversing different structures

### TypeScript Signature
```typescript
// Iterator interface
interface Iterator<T> {
  next(): { value: T; done: boolean };
  hasNext(): boolean;
}

// Iterable collection
interface Iterable<T> {
  createIterator(): Iterator<T>;
}

// Concrete iterator
class ArrayIterator<T> implements Iterator<T> {
  private position = 0;

  constructor(private collection: T[]) {}

  next(): { value: T; done: boolean } {
    if (this.position < this.collection.length) {
      return { value: this.collection[this.position++], done: false };
    }
    return { value: null as any, done: true };
  }

  hasNext(): boolean {
    return this.position < this.collection.length;
  }
}

// Collection
class NumberCollection implements Iterable<number> {
  constructor(private items: number[]) {}

  createIterator(): Iterator<number> {
    return new ArrayIterator(this.items);
  }
}
```

### JavaScript Native Support
```typescript
// Symbol.iterator
const collection = {
  items: [1, 2, 3],
  [Symbol.iterator]() {
    let index = 0;
    const items = this.items;
    return {
      next() {
        return index < items.length
          ? { value: items[index++], done: false }
          : { done: true, value: undefined };
      }
    };
  }
};

for (const item of collection) {
  console.log(item); // 1, 2, 3
}

// Generator (simpler)
function* numberGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

for (const num of numberGenerator()) {
  console.log(num);
}
```

---

## Mediator

### Definition
Defines an object that encapsulates how a set of objects interact, promoting loose coupling by keeping objects from referring to each other explicitly.

### When to Use
- [x] Set of objects communicate in complex ways
- [x] Reusing object is difficult because it refers to many others
- [x] Behavior distributed between classes should be customizable without subclassing

### TypeScript Signature
```typescript
// Mediator interface
interface Mediator {
  notify(sender: object, event: string): void;
}

// Concrete mediator
class ConcreteMediator implements Mediator {
  private component1: Component1;
  private component2: Component2;

  constructor(c1: Component1, c2: Component2) {
    this.component1 = c1;
    this.component1.setMediator(this);
    this.component2 = c2;
    this.component2.setMediator(this);
  }

  notify(sender: object, event: string): void {
    if (event === 'A') {
      console.log('Mediator reacts to A and triggers:');
      this.component2.doC();
    }
    if (event === 'D') {
      console.log('Mediator reacts to D and triggers:');
      this.component1.doB();
    }
  }
}

// Base component
class BaseComponent {
  protected mediator: Mediator | null = null;

  setMediator(mediator: Mediator): void {
    this.mediator = mediator;
  }
}

// Concrete components
class Component1 extends BaseComponent {
  doA(): void {
    console.log('Component 1 does A');
    this.mediator?.notify(this, 'A');
  }

  doB(): void {
    console.log('Component 1 does B');
  }
}

class Component2 extends BaseComponent {
  doC(): void {
    console.log('Component 2 does C');
  }

  doD(): void {
    console.log('Component 2 does D');
    this.mediator?.notify(this, 'D');
  }
}

// Usage
const c1 = new Component1();
const c2 = new Component2();
const mediator = new ConcreteMediator(c1, c2);

c1.doA();
// Output:
// Component 1 does A
// Mediator reacts to A and triggers:
// Component 2 does C
```

### Stack-Native: React Context
```typescript
const ChatContext = createContext<ChatMediator>(null!);

// Mediator as context
function ChatRoom({ children }: Props) {
  const sendMessage = (from: string, to: string, msg: string) => {
    // Mediator logic
  };

  return (
    <ChatContext.Provider value={{ sendMessage }}>
      {children}
    </ChatContext.Provider>
  );
}
```

### Code Smells It Fixes
- **Complex web of interactions**: Centralized in mediator
- **God object with many responsibilities**: Mediator focuses on coordination only

---

## Memento

### Definition
Captures and externalizes an object's internal state without violating encapsulation, so the object can be restored to this state later.

### When to Use
- [x] Need to save/restore object snapshots (undo/redo)
- [x] Direct interface to state would expose implementation
- [x] Want to preserve encapsulation boundaries

### TypeScript Signature
```typescript
// Memento
class Memento {
  constructor(private state: string, private date: Date) {}

  getState(): string {
    return this.state;
  }

  getDate(): Date {
    return this.date;
  }
}

// Originator
class Editor {
  private content: string = '';

  type(text: string): void {
    this.content += text;
  }

  getContent(): string {
    return this.content;
  }

  save(): Memento {
    return new Memento(this.content, new Date());
  }

  restore(memento: Memento): void {
    this.content = memento.getState();
  }
}

// Caretaker
class History {
  private mementos: Memento[] = [];

  push(memento: Memento): void {
    this.mementos.push(memento);
  }

  pop(): Memento | undefined {
    return this.mementos.pop();
  }
}

// Usage
const editor = new Editor();
const history = new History();

editor.type('Hello ');
history.push(editor.save());

editor.type('World');
history.push(editor.save());

editor.type('!!!');
console.log(editor.getContent()); // Hello World!!!

editor.restore(history.pop()!);
console.log(editor.getContent()); // Hello World
```

### Code Smells It Fixes
- **Exposing internal state for undo**: Memento encapsulates state
- **Complex undo logic**: History manages snapshots

---

## Observer

### Definition
Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified automatically.

### When to Use
- [x] Change to one object requires changing others (unknown number)
- [x] Object should notify others without knowing who they are
- [x] Event-driven architectures
- [x] Reactive programming

### TypeScript Signature
```typescript
// Observer interface
interface Observer {
  update(subject: Subject): void;
}

// Subject
interface Subject {
  attach(observer: Observer): void;
  detach(observer: Observer): void;
  notify(): void;
}

// Concrete subject
class ConcreteSubject implements Subject {
  private observers: Observer[] = [];
  private state: number = 0;

  attach(observer: Observer): void {
    if (!this.observers.includes(observer)) {
      this.observers.push(observer);
    }
  }

  detach(observer: Observer): void {
    const index = this.observers.indexOf(observer);
    if (index !== -1) {
      this.observers.splice(index, 1);
    }
  }

  notify(): void {
    for (const observer of this.observers) {
      observer.update(this);
    }
  }

  setState(state: number): void {
    this.state = state;
    this.notify();
  }

  getState(): number {
    return this.state;
  }
}

// Concrete observers
class ConcreteObserverA implements Observer {
  update(subject: ConcreteSubject): void {
    console.log(`ObserverA: State is now ${subject.getState()}`);
  }
}

class ConcreteObserverB implements Observer {
  update(subject: ConcreteSubject): void {
    console.log(`ObserverB: State is now ${subject.getState()}`);
  }
}

// Usage
const subject = new ConcreteSubject();
const observerA = new ConcreteObserverA();
const observerB = new ConcreteObserverB();

subject.attach(observerA);
subject.attach(observerB);

subject.setState(5);
// Output:
// ObserverA: State is now 5
// ObserverB: State is now 5
```

### Stack-Native Alternatives

**React**:
```typescript
const [value, setValue] = useState(0);
useEffect(() => {
  // Auto-notified on value change
}, [value]);
```

**RxJS**:
```typescript
const subject = new BehaviorSubject(0);
subject.subscribe(value => console.log(value));
subject.next(5); // Notifies subscribers
```

**Angular**:
```typescript
private data$ = new BehaviorSubject<Data>(initial);
getData() { return this.data$.asObservable(); }
```

### Code Smells It Fixes
- **Scattered notification logic**: Centralized in subject
- **Tight coupling**: Observers don't know about each other

### Common Mistakes
- **Memory leaks**: Forgetting to unsubscribe/detach
- **Notification storms**: Too many updates triggering cascades
- **Order dependency**: Observers should be independent

---

## State

### Definition
Allows an object to alter its behavior when its internal state changes, appearing to change its class.

### When to Use
- [x] Object behavior depends on its state
- [x] Operations have large conditional statements that depend on state
- [x] State transitions are well-defined

### TypeScript Signature
```typescript
// State interface
interface State {
  handle(context: Context): void;
}

// Context
class Context {
  private state: State;

  constructor(initialState: State) {
    this.state = initialState;
  }

  setState(state: State): void {
    console.log(`Context: Transitioning to ${state.constructor.name}`);
    this.state = state;
  }

  request(): void {
    this.state.handle(this);
  }
}

// Concrete states
class ConcreteStateA implements State {
  handle(context: Context): void {
    console.log('StateA handles request');
    context.setState(new ConcreteStateB());
  }
}

class ConcreteStateB implements State {
  handle(context: Context): void {
    console.log('StateB handles request');
    context.setState(new ConcreteStateA());
  }
}

// Usage
const context = new Context(new ConcreteStateA());
context.request(); // StateA handles request, transitions to StateB
context.request(); // StateB handles request, transitions to StateA
```

### Real-World: Document States
```typescript
interface DocumentState {
  publish(doc: Document): void;
  review(doc: Document): void;
}

class Draft implements DocumentState {
  publish(doc: Document): void {
    console.log('Cannot publish draft directly');
  }
  review(doc: Document): void {
    console.log('Sending for review');
    doc.setState(new InReview());
  }
}

class InReview implements DocumentState {
  publish(doc: Document): void {
    console.log('Publishing document');
    doc.setState(new Published());
  }
  review(doc: Document): void {
    console.log('Already in review');
  }
}

class Published implements DocumentState {
  publish(doc: Document): void {
    console.log('Already published');
  }
  review(doc: Document): void {
    console.log('Cannot review published document');
  }
}

class Document {
  private state: DocumentState = new Draft();

  setState(state: DocumentState): void {
    this.state = state;
  }

  publish(): void {
    this.state.publish(this);
  }

  review(): void {
    this.state.review(this);
  }
}
```

### Stack-Native: React useReducer
```typescript
const reducer = (state: State, action: Action) => {
  switch (action.type) {
    case 'DRAFT': return { status: 'draft' };
    case 'REVIEW': return { status: 'review' };
    case 'PUBLISHED': return { status: 'published' };
  }
};

const [state, dispatch] = useReducer(reducer, { status: 'draft' });
```

### Code Smells It Fixes
- **Complex conditionals on state**: Each state is a separate class
- **Scattered state-dependent behavior**: Localized in state classes

---

## Strategy

### Definition
Defines a family of algorithms, encapsulates each one, and makes them interchangeable, letting the algorithm vary independently from clients.

### When to Use
- [x] Many related classes differ only in behavior
- [x] Need different variants of an algorithm
- [x] Algorithm uses data clients shouldn't know about
- [x] Class has multiple conditional statements for selecting behavior

### TypeScript Signature
```typescript
// Strategy interface
interface Strategy {
  execute(a: number, b: number): number;
}

// Concrete strategies
class AddStrategy implements Strategy {
  execute(a: number, b: number): number {
    return a + b;
  }
}

class MultiplyStrategy implements Strategy {
  execute(a: number, b: number): number {
    return a * b;
  }
}

// Context
class Calculator {
  constructor(private strategy: Strategy) {}

  setStrategy(strategy: Strategy): void {
    this.strategy = strategy;
  }

  calculate(a: number, b: number): number {
    return this.strategy.execute(a, b);
  }
}

// Usage
const calculator = new Calculator(new AddStrategy());
console.log(calculator.calculate(5, 3)); // 8

calculator.setStrategy(new MultiplyStrategy());
console.log(calculator.calculate(5, 3)); // 15
```

### Stack-Native: React Hooks
```typescript
// Strategies as hooks
const useCreditPayment = () => ({ process: async (amount) => { /* ... */ } });
const usePaypalPayment = () => ({ process: async (amount) => { /* ... */ } });

const usePaymentStrategy = (type: PaymentType) => {
  const strategies = {
    credit: useCreditPayment(),
    paypal: usePaypalPayment(),
  };
  return strategies[type];
};

// Usage in component
const PaymentForm = ({ type }: Props) => {
  const strategy = usePaymentStrategy(type);
  const handlePay = () => strategy.process(amount);
};
```

### Code Smells It Fixes
- **Switch on type**: `switch (type) { case 'A': ... case 'B': ... }`
  → Replace with strategy selection
- **Hardcoded algorithms**: Strategies are interchangeable

### Common Mistakes
- **Strategy explosion**: Too many small strategies
- **Client awareness**: Client shouldn't know strategy details

---

## Template Method

### Definition
Defines the skeleton of an algorithm in a method, deferring some steps to subclasses, letting subclasses redefine certain steps without changing structure.

### When to Use
- [x] Implement invariant parts of algorithm once, leave varying parts to subclasses
- [x] Common behavior among subclasses should be factored and localized
- [x] Control subclass extensions (hook operations)

### TypeScript Signature
```typescript
abstract class AbstractClass {
  // Template method
  templateMethod(): void {
    this.baseOperation1();
    this.requiredOperation1();
    this.baseOperation2();
    this.hook();
    this.requiredOperation2();
  }

  // Implemented operations
  baseOperation1(): void {
    console.log('AbstractClass: base operation 1');
  }

  baseOperation2(): void {
    console.log('AbstractClass: base operation 2');
  }

  // Must be implemented by subclasses
  abstract requiredOperation1(): void;
  abstract requiredOperation2(): void;

  // Hook (optional override)
  hook(): void {
    // Default empty implementation
  }
}

class ConcreteClassA extends AbstractClass {
  requiredOperation1(): void {
    console.log('ConcreteClassA: operation 1');
  }

  requiredOperation2(): void {
    console.log('ConcreteClassA: operation 2');
  }

  hook(): void {
    console.log('ConcreteClassA: hook override');
  }
}

class ConcreteClassB extends AbstractClass {
  requiredOperation1(): void {
    console.log('ConcreteClassB: operation 1');
  }

  requiredOperation2(): void {
    console.log('ConcreteClassB: operation 2');
  }
}

// Usage
const classA = new ConcreteClassA();
classA.templateMethod();
```

### Code Smells It Fixes
- **Duplicated algorithm structure**: Template defines common steps
- **Inconsistent step order**: Template enforces order

---

## Visitor

### Definition
Represents an operation to be performed on elements of an object structure, letting you define new operations without changing classes of elements.

### When to Use
- [x] Object structure contains many classes with differing interfaces
- [x] Many distinct operations need to be performed on objects
- [x] Object structure rarely changes but operations on it often do

### TypeScript Signature
```typescript
// Element interface
interface Element {
  accept(visitor: Visitor): void;
}

// Concrete elements
class ConcreteElementA implements Element {
  accept(visitor: Visitor): void {
    visitor.visitConcreteElementA(this);
  }

  operationA(): string {
    return 'A';
  }
}

class ConcreteElementB implements Element {
  accept(visitor: Visitor): void {
    visitor.visitConcreteElementB(this);
  }

  operationB(): string {
    return 'B';
  }
}

// Visitor interface
interface Visitor {
  visitConcreteElementA(element: ConcreteElementA): void;
  visitConcreteElementB(element: ConcreteElementB): void;
}

// Concrete visitor
class ConcreteVisitor implements Visitor {
  visitConcreteElementA(element: ConcreteElementA): void {
    console.log(`Visiting A: ${element.operationA()}`);
  }

  visitConcreteElementB(element: ConcreteElementB): void {
    console.log(`Visiting B: ${element.operationB()}`);
  }
}

// Usage
const elements: Element[] = [
  new ConcreteElementA(),
  new ConcreteElementB(),
];

const visitor = new ConcreteVisitor();
for (const element of elements) {
  element.accept(visitor);
}
```

### Code Smells It Fixes
- **Adding new operations requires modifying elements**: Visitor externalizes operations
- **Operations scattered across classes**: Visitor groups related operations

### Common Mistakes
- **Adding new element types**: Requires modifying all visitors (rigid)
- **Breaking encapsulation**: Visitor may need access to internals

---

## Interpreter

### Definition
Defines a representation for a grammar along with an interpreter that uses the representation to interpret sentences in the language.

### When to Use
- [x] Grammar is simple (for complex grammars, use parser generators)
- [x] Efficiency is not critical
- [x] Building a simple domain-specific language (DSL)

### TypeScript Signature
```typescript
// Context
class Context {
  constructor(public input: string) {}
}

// Abstract expression
interface Expression {
  interpret(context: Context): number;
}

// Terminal expression
class NumberExpression implements Expression {
  constructor(private value: number) {}

  interpret(context: Context): number {
    return this.value;
  }
}

// Non-terminal expressions
class AddExpression implements Expression {
  constructor(private left: Expression, private right: Expression) {}

  interpret(context: Context): number {
    return this.left.interpret(context) + this.right.interpret(context);
  }
}

class MultiplyExpression implements Expression {
  constructor(private left: Expression, private right: Expression) {}

  interpret(context: Context): number {
    return this.left.interpret(context) * this.right.interpret(context);
  }
}

// Usage: (5 + 3) * 2
const context = new Context('(5 + 3) * 2');
const expression = new MultiplyExpression(
  new AddExpression(
    new NumberExpression(5),
    new NumberExpression(3)
  ),
  new NumberExpression(2)
);

console.log(expression.interpret(context)); // 16
```

### Code Smells It Fixes
- **Complex parsing logic**: Grammar rules are explicit classes
- **Hardcoded language interpretation**: Extensible grammar

---

## Summary Table

| Pattern | Complexity | Use Frequency | Main Benefit |
|---------|------------|---------------|--------------|
| Chain of Responsibility | Medium | Medium | Decouple sender from receiver |
| Command | Medium | Medium | Parameterize, queue, undo operations |
| Iterator | Low | High | Sequential access without exposure |
| Mediator | Medium | Medium | Reduce coupling between objects |
| Memento | Medium | Low | Save/restore state |
| Observer | Low | Very High | One-to-many notifications |
| State | Medium | Medium | State-dependent behavior |
| Strategy | Low | High | Interchangeable algorithms |
| Template Method | Medium | Medium | Algorithm skeleton with variants |
| Visitor | High | Low | Operations on object structure |
| Interpreter | High | Very Low | Simple DSL interpretation |

## Best Practices

1. **Observer**: Always unsubscribe to prevent memory leaks
2. **Strategy vs State**: Strategy changes behavior externally; State changes internally
3. **Use framework patterns**: React hooks, RxJS, Redux provide these patterns
4. **Command for undo**: Store history of command objects
5. **Chain of Responsibility**: Keep handlers simple, ensure request is handled

## References

- *Design Patterns: Elements of Reusable Object-Oriented Software* (Gang of Four)
- [Refactoring Guru: Behavioral Patterns](https://refactoring.guru/design-patterns/behavioral-patterns)
- [RxJS Documentation](https://rxjs.dev/)

```