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
-
Stack Detection: Identify primary framework/library (React, Angular, NestJS, Vue, Express, RxJS, Redux, ORMs)
-
Pattern Detection: Find existing implementations of 23 GoF patterns
-
Smart Suggestions: Recommend patterns to fix code smells, using stack-native idioms when available
-
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:
- Stack Detection (package.json, tsconfig.json, framework files)
- Pattern Search (Glob for candidates → Grep for signatures → Read for validation)
- Classification (native to stack vs custom implementations)
- Confidence Scoring (0.0-1.0 based on detection rules)
- 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:
- Code Smell Detection (switch statements, long parameter lists, global state, etc.)
- Pattern Matching (map smell → applicable patterns)
- Stack Adaptation (prefer native framework patterns over custom implementations)
- Priority Ranking (impact × feasibility)
- 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:
- Pattern Identification (which pattern is implemented)
- Criteria Assessment (correctness, testability, SOLID compliance, documentation)
- Issue Detection (common mistakes, anti-patterns)
- Scoring (0-10 per criterion)
- 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):
-
package.json → Check dependencies and devDependencies
-
Framework-specific files → angular.json , next.config.* , nest-cli.json , vite.config.*
-
tsconfig.json → Check compilerOptions, paths, lib
-
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:
{ "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:
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.
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
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 ):
-
Switch on Type → Strategy/Factory pattern
-
Long Parameter List (>4) → Builder pattern
-
Global State Access → Singleton (or preferably DI)
-
Duplicated Conditionals on State → State pattern
-
Scattered Notification Logic → Observer pattern
-
Complex Object Creation → Factory/Abstract Factory
-
Tight Coupling to Concrete Classes → Adapter/Bridge
-
Repetitive Interface Conversions → Adapter pattern
-
Deep Nesting for Feature Addition → Decorator pattern
-
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 ):
-
Correctness (0-10): Does it match the canonical pattern structure?
-
Testability (0-10): Can dependencies be mocked/stubbed easily?
-
Single Responsibility (0-10): Does it do one thing only?
-
Open/Closed Principle (0-10): Extensible without modification?
-
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)
{ "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)
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):
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):
// 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)
// 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
# 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
# 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
# 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