design-patterns

v2026.09.24

Select a design pattern from a symptom — strategy, observer, factory, adapter, decorator. Use when a structure resists change, or choosing between Gang-of-Four patterns.

GitHub
安装命令
npx skhub add laurigates/design-patterns
Markdown
SKILL.md

Design Patterns: Symptom → Pattern

The Gang-of-Four patterns are answers to recurring design problems. Reaching for a pattern by name invites over-engineering; reaching for one by symptom keeps the design honest. This skill maps the pressure you're feeling — "this switch grows every time we add a type", "callers keep re-implementing the same multi-step setup" — to the pattern that relieves it, and just as importantly says when no pattern is the right call.

For the per-pattern intent, structure, and a minimal recipe, see REFERENCE.md. This body is the selector.

When to Use This Skill

Use this skill when...Use something else instead when...
A structure resists a change that should be easy (new type, new behaviour)Removing duplication with no design pressure → code-quality-plugin:dry-consolidation
Choosing between two patterns, or unsure a pattern is warrantedMechanical refactor toward pure functions → code-quality-plugin:code-refactor
Naming the pattern already latent in a pile of conditionalsComplexity metrics on a function → code-quality-plugin:code-complexity
Teaching/justifying a pattern choice in reviewUI/component composition patterns → component-patterns-plugin

Selector

Match the symptom, not the noun. Confirm the pressure is real before adopting any pattern — each adds an indirection that a one-off conditional does not.

Symptom you feelCandidate patternConfirm before adopting
A switch/if on a type code grows with every new variantStrategy / State≥2 variants exist and more are expected
Object behaviour changes with an internal mode, transitions are tangledStateThe modes have distinct transitions, not just a flag
Many objects must react when one changesObserverReactors are genuinely decoupled from the source
Callers hard-code which concrete class to instantiateFactory Method / Abstract FactoryThe choice varies at runtime or by config
An interface you need ≠ the interface you have (3rd-party/legacy)AdapterYou can't change the callee directly
Behaviour to add/remove per-instance at runtime, combinatoriallyDecoratorSubclass explosion is the alternative
Constructing one object needs many ordered steps/optionsBuilderThe telescoping constructor actually hurts
A subsystem is too many moving parts for callersFacadeCallers only need a common subset
An algorithm's skeleton is fixed but steps varyTemplate Method / StrategyThe skeleton truly is stable
Traversal logic leaks across a collection's clientsIteratorThe collection's shape is non-trivial
Operations sprawl across a type hierarchy you can't growVisitorThe hierarchy is stable but operations churn

When two fit: Strategy (composition) over Template Method (inheritance) unless the skeleton must be enforced; State over Strategy when the variants drive transitions between each other.

Parameters

Parse $ARGUMENTS:

  • Symptom or target (optional) — a free-text symptom/requirement, or a file/diff to assess for latent patterns. If absent, default to the current change (git diff HEAD) and scan it for the symptoms above.

Execution

Execute this pattern selection:

Step 1: Name the pressure

State, in one line, the change that is currently hard — the new type, the new reactor, the runtime choice. If the target is code, locate the growing conditional / hard-coded new / leaking interface that signals it. If nothing resists change, stop and say so: no pattern is warranted.

Step 2: Match symptom → candidate

Use the selector to pick 1-2 candidates. Read their intent in REFERENCE.md to confirm fit. State explicitly what each pattern costs (an extra interface, an indirection, a new type to maintain).

Step 3: Justify or reject

Apply the "confirm before adopting" gate for the chosen pattern. If the variants don't yet exist (YAGNI) or only one ever will, recommend the simpler conditional and reject the pattern with the reason. Patterns earn their cost only against real, recurring variation.

Step 4: Recommend

Emit: the symptom, the chosen pattern (or "no pattern — keep the conditional"), the cost it adds, and the minimal shape from REFERENCE.md mapped onto the target's own types. Keep it a recommendation; don't rewrite the code wholesale.

Anti-patterns

MistakeCorrect approach
Picking a pattern by its cool nameStart from the symptom; let it select the pattern
Adding Strategy for a single, stable behaviourOne implementation = no pattern; YAGNI
Abstract Factory where a function would doUse the lightest construct that removes the pressure
Stacking patterns "to be enterprise-ready"Each indirection is cost; adopt one only against real variation

Quick Reference

PressurePatternCost
Type-code switch growsStrategy / StateOne interface + N classes
Mode-driven behaviour & transitionsStateState classes + transition wiring
Fan-out reactionsObserverSubscription lifecycle
Hard-coded newFactoryAn extra creation seam
Wrong interface, can't change calleeAdapterA thin translation layer
Per-instance runtime behaviourDecoratorWrapper chain

Related

  • REFERENCE.md — per-pattern intent, structure, minimal recipe
  • code-quality-plugin:dry-consolidation — when the pressure is duplication, not variation, dedupe instead of patterning
  • code-quality-plugin:code-refactor — the mechanical moves that introduce the chosen pattern
  • software-design-plugin:design-deep-modules — a pattern should deepen the interface, not add a shallow indirection layer
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

MIT

源路径

software-design-plugin/skills/design-patterns

默认分支

main

最新提交

1668324

Tree SHA

b2d4cc3