Comprehensive GoF design patterns analyzer with stack-aware suggestions. **Features**: - Detects 23 GoF patterns (Creational, Structural, Behavioral) - Stack detection (React, Angular, NestJS, Vue, Express, RxJS, Redux, ORMs) - Code smell detection with pattern suggestions - Quality evaluation (5 criteria scoring) - Prefers stack-native alternatives (e.g., React Context over Singleton) **Structure**: - 9 files: SKILL.md + reference docs + detection rules + evaluation checklists - 3 operating modes: Detection, Suggestion, Evaluation - Pattern-specific documentation for all 23 GoF patterns **Documentation**: - Added comprehensive example in guide section 5.4 - Updated examples/README.md with skill entry - Updated template count: 65 → 66 **Use cases**: - Analyze existing patterns in codebase - Suggest refactoring with stack-native patterns - Evaluate pattern implementation quality Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
565 lines
18 KiB
Markdown
565 lines
18 KiB
Markdown
---
|
||
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
|