From design-patterns
Always-on GoF design pattern catalog (Gang of Four, refactoring.guru). Use for: new class, new interface, new abstract class, refactor, refactoring, abstraction, architecture, design review, code review, planning, feature design, system design, architectural decision, architectural trade-off, OOP design, inheritance, composition, polymorphism, SOLID, design pattern, pattern check, factory, factory method, abstract factory, builder, prototype, singleton, adapter, bridge, composite, decorator, facade, flyweight, proxy, chain of responsibility, command, iterator, mediator, memento, observer, state, strategy, template method, visitor, creational, structural, behavioral. Sourced from refactoring.guru/design-patterns/typescript. Tier 1 (3-star) must be considered first: Factory Method, Abstract Factory, Builder, Singleton, Adapter, Facade, Strategy, Observer, Iterator, Template Method. Per-pattern TypeScript references in references/.
How this skill is triggered — by the user, by Claude, or both
Slash command
/design-patterns:design-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Canonical GoF catalog. 22 patterns, 3 tiers by popularity. Every Write/Edit
PORTING.mdbuild-antisignals.jsreferences/_antisignals.jsonreferences/abstract-factory.mdreferences/adapter.mdreferences/bridge.mdreferences/builder.mdreferences/chain-of-responsibility.mdreferences/command.mdreferences/composite.mdreferences/decorator.mdreferences/facade.mdreferences/factory-method.mdreferences/flyweight.mdreferences/iterator.mdreferences/mediator.mdreferences/memento.mdreferences/observer.mdreferences/prototype.mdreferences/proxy.mdCanonical GoF catalog. 22 patterns, 3 tiers by popularity. Every Write/Edit
on a .ts/.tsx source file with substantive new logic must trigger a
Pattern check — even bug fixes, new functions, and refactors that don't
declare a class. Most answer no GoF pattern — rejected; that is correct.
Default form — emit this for most bug fixes, small edits, and single-caller code:
Pattern check: no GoF pattern (-) — rejected — <reason ≥20 chars>.
Only when a pattern genuinely applies:
Pattern check: <PatternName> (Tier <N>) — applied — <reason ≥20 chars>.
Pattern check: <PatternName> (Tier <N>) — extended — <cite existing project class>.
<decision> is one of applied (new pattern instance), extended (extends
existing project pattern family per
.claude/design-patterns-project-usage.md), or rejected (anti-overuse —
inline code is correct here).<reason> must be ≥ 20 chars. One-word reasons ("bug fix", "cleanup") are
rejected by the hook.Pattern check: <Name> (Tier N) — <reason> still works but the
structured form above is preferred (enables aggregation and typo catching).No silent class creation. No silent interface design. Always declare intent.
Bypass for mechanical codemods / bulk renames: add
// pattern-check: skip <reason> to the file payload (not a replacement for
the preamble on substantive edits).
Most edits answer Pattern check: no GoF pattern — rejected — <reason>. That
is the right default. The enforcement hook fires on every substantive edit,
but firing ≠ a pattern is required. It means the decision is required.
Patterns are tools, not goals. Do NOT introduce a pattern when:
new (YAGNI)This rule overrides "always pick a Tier 1 pattern". Project ethos: three similar lines of code beats a premature abstraction.
When the rule applies, emit:
Pattern check: no GoF pattern (-) — rejected — <specific reason, ≥20 chars>.
The reason should explain why this case is fine inline (e.g. "single caller, 8 lines, no indication of second implementation" or "bug fix in guard clause, no structural change"). Vague reasons like "bug fix" are rejected.
references/<slug>.md for the chosen pattern (full intent, code, "Don't use when"). Cross-check project-specific guidance in .claude/design-patterns-project-usage.mdno GoF patternBefore running the full decision tree, ask these three questions in order:
no GoF patternno GoF pattern.claude/design-patterns-project-usage.md)? → extend existing pattern;
use decision: extended and cite the class.If all three are "no", continue to §5.
The pattern-context-prep.js PreToolUse hook runs before the blocking
preamble validator. On substantive edits it emits a PATTERN-CONTEXT:
stderr block with candidate sibling paths, the matching project pattern
family, recent decisions on this file, and imports already present. Three
modes — the agent's response rules depend on which mode fired:
PATTERN-CONTEXT: advisory — read 1–3 siblings before Pattern check
triggered-by: new class, diff 62 lines
family-hint: src/<feature>/base.ts (Adapter + Strategy — example family)
siblings:
- src/<feature>/base.ts
- src/<feature>/impl-a.ts
recent-decisions-on-file:
- 2026-04-18 extended Adapter — "impl-b.ts mirrors impl-a.ts shape"
imports-in-payload:
- ../<feature>/base (looks like family extension)
action: Read 1–3 of the listed paths, then emit Pattern check citing one.
END-PATTERN-CONTEXT
Rule 1: agent MUST Read 1–3 hinted paths (family-hint first, then
siblings) before emitting Pattern check:. The preamble must either:
applied or extended), ORscanned N siblings, no family match plus an
anti-extended phrase (isolated, no-siblings, unrelated domain) to
justify rejected.PATTERN-CONTEXT: already-in-family
family: Adapter + Strategy (example family) — via src/<feature>/base.ts
last-extend: 2026-04-18 — impl-a.ts shape
note: no re-read required; emit `Pattern check: <pattern> — extended —
continuing existing integration via <path>`.
END-PATTERN-CONTEXT
Rule 2: NO sibling Read required. Emit extended — continuing <family> via <cached-path> directly. Saves tokens on routine edits to files already
confirmed in a family. The citation/anti-extended validators are
auto-satisfied by the session cache for this file.
Appears as an additional line inside a Mode A block when the decision log
shows ≥3 refactor-suggest or refactor-candidate entries against the
same family within the last 30 days.
Rule 3: after Reading one of the hinted paths, if the existing family
is misapplied or a better pattern fits, emit refactor-suggest with
<CurrentPattern>→<BetterPattern> and a cited path. The current edit
still proceeds minimally — the suggestion lands in the decision log as an
open entry that /pattern-review --backlog surfaces.
Required form for refactor-suggest:
Pattern check: Facade→Facade+Strategy (Tier 1) — refactor-suggest —
current facade has 12 methods (god-class risk); splitting by action-type
Strategy keyed on src/<feature>/dispatcher.ts would isolate dispatch.
Validator requirements: arrow → in pattern name, reason ≥ 40 chars,
cite a real .ts/.tsx path.
Example A (Mode A → extended). PATTERN-CONTEXT lists
src/<feature>/base.ts + siblings. Agent Reads base.ts, sees the
IPort interface, emits:
Pattern check: Adapter (Tier 1) — extended — new impl-b.ts implements
IPort from src/<feature>/base.ts; mirrors impl-a.ts shape.
Example B (Mode A → rejected after scan). PATTERN-CONTEXT lists three
*Handler.ts siblings for a utility file. Agent Reads one, finds no
shared base:
Pattern check: no GoF pattern (-) — rejected — scanned 3 siblings, no
family match; isolated 22-line helper for date parsing.
Example C (Mode B → extended short). PATTERN-CONTEXT already-in-family:
Pattern check: Adapter (Tier 1) — extended — continuing existing
integration via src/<feature>/base.ts.
Example D (Mode C → refactor-suggest). PATTERN-CONTEXT shows
family-health: degraded on a 12-method facade:
Pattern check: Facade→Facade+Strategy (Tier 1) — refactor-suggest —
facade has 12 public methods (god-class); splitting verbs into
strategies keyed on action via src/<feature>/dispatcher.ts would
isolate dispatch.
§2 overrides this preflight. Do NOT emit refactor-suggest for <50-line
single-caller code just because the hook offered siblings. The preflight
gives you information; judgement stays yours.
Need to create objects?
├─ One concrete type, no swap → just `new`, no pattern
├─ Pick concrete type at runtime → Factory Method
├─ Families of related types → Abstract Factory
├─ Many constructor params / step-by-step build → Builder
├─ Exactly one instance globally → Singleton (last resort — usually a registry)
└─ Cheap clone of an existing instance → Prototype
Need to compose / wrap / bridge structures?
├─ Incompatible interfaces → Adapter
├─ Hide a complex subsystem → Facade
├─ Add behavior without subclass explosion → Decorator
├─ Tree of part-whole → Composite
├─ Lazy / access control / remote stand-in → Proxy
├─ Two independent dimensions of variation → Bridge
└─ Many small objects sharing intrinsic state → Flyweight
Need objects to communicate?
├─ Swap algorithms at runtime → Strategy
├─ Notify N listeners on event → Observer
├─ Walk a collection without exposing internals → Iterator
├─ Algorithm skeleton with overridable steps → Template Method
├─ Encapsulate request as object (queue / undo / log) → Command
├─ Object behavior depends on internal state → State
├─ Pass request through handler chain → Chain of Responsibility
├─ Hub coordinating N peer objects → Mediator
├─ Snapshot for undo without exposing internals → Memento
└─ Add operations to a class hierarchy without modifying it → Visitor
| If you need... | Use |
|---|---|
| Swap algorithms at runtime | Strategy |
| Wrap an incompatible API | Adapter |
| Hide a complex subsystem | Facade |
| Pick concrete class at runtime | Factory Method |
| Notify N subscribers on event | Observer |
| Walk a collection opaquely | Iterator |
| Algorithm skeleton with overridable steps | Template Method |
| Single global instance | Singleton (last resort) |
| Build complex object step-by-step | Builder |
| Families of related products | Abstract Factory |
| Encapsulate a request (undo/queue/log) | Command |
| State-dependent behavior | State |
| Tree of part-whole, treated uniformly | Composite |
| Stack runtime behaviors on object | Decorator |
| Pipeline of handlers | Chain of Responsibility |
| Combo | Use case |
|---|---|
| Strategy + Factory Method | Pluggable algorithm where the factory picks the concrete strategy |
| Command + Memento | Undo/redo |
| Observer + Mediator | Event bus where the mediator dispatches to observers |
| Composite + Iterator | Tree walking |
| Facade + Adapter | Facade hiding multiple Adapters over different backends |
| State + Strategy | Strategy for the active behavior, State for switching strategies |
| Decorator + Strategy | Stack decorators on top of a base strategy |
newif (type === 'foo') chain → use Strategy or polymorphismextends to grab methods → use composition / Strategy / DecoratorWhen the planning workflow runs (Plan agent, ExitPlanMode plans, design discussions):
Plans without Pattern check: lines for new abstractions are incomplete.
This skill's content lives in this skill, NOT in any user memory system. Do not save pattern definitions, examples, or star ratings to memory. Memory is for user preferences and project state, not catalogs.
If you find an existing memory entry that duplicates this skill's content, delete it.
npx claudepluginhub wolffyx/design-patterns --plugin design-patternsCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.