Recognizes structural situations that match known design patterns and recommends whether to apply them — or explains why the pattern doesn't fit. Use when the user has a structural problem and is considering a pattern, when reviewing a design that uses a pattern questionably, or when the user asks which pattern fits their situation.
Install with Tessl CLI
npx tessl i github:santosomar/general-secure-coding-agent-skills --skill design-pattern-suggestor90
Quality
87%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
A pattern is a named solution to a recurring structural problem. The value is the vocabulary, not the code. The risk is applying a pattern because it's familiar, not because the problem it solves is present.
Start from the symptom. The pattern is the answer; the problem is the question.
| Symptom | Pattern | Or maybe just… |
|---|---|---|
| Switch on type code, same switch in 3+ places | Strategy / State | …one switch if it's only in one place |
| Constructor has 8 parameters, 5 are optional | Builder | …keyword arguments with defaults |
| Need exactly one of a thing, globally | Singleton | …a module-level variable (in Python/JS) |
| Class hierarchy × orthogonal dimension = class explosion | Decorator / Bridge | …composition with a field |
| Creating objects, but which concrete type depends on runtime data | Factory | …a dict {key: constructor} — often enough |
| Many objects need to know when one object changes | Observer | …a callback list — that IS observer |
| Different interface than what you have, can't change either side | Adapter | Usually correct, rarely over-applied |
| Need undo, or need to queue/log/serialize operations | Command | Usually correct |
| Traversing a composite structure uniformly | Visitor / Iterator | …if the structure rarely changes, just recurse |
Most pattern misuse is applying GoF ceremony where the language already gives you the mechanism for free:
strategies = {"a": fn_a, "b": fn_b} is the pattern.import config — done.addEventListener, signals, Rx — the pattern is built into the runtime.yield / generators. You don't write hasNext()/next().If the "or maybe just" fits, use it. The pattern is the fallback for languages that lack the mechanism.
Sometimes the finding is "you're using a pattern wrong":
| Anti-pattern | Symptom |
|---|---|
| Singleton-as-global | Singleton exists to avoid passing a dependency — hidden coupling, untestable |
| Factory-for-one | UserFactory.create() returns new User() — the factory adds nothing |
| Observer soup | 10 observers, firing order matters, some observers trigger other observers — you've built an implicit state machine |
| Premature Strategy | One concrete strategy. The interface exists "in case we need another." → speculative generality |
| Visitor on a stable hierarchy | The hierarchy never changes; visitor's indirection buys nothing |
Symptom: "Every time we add a payment method we have to edit process_payment() and validate_payment() and refund_payment() — three switches on method_type."
Match: Same switch, 3 places, on a type code → Strategy.
Check the "or maybe just": What language? Java. No first-class functions pre-lambdas (or the team doesn't use them). Strategy is the idiomatic fit.
Recommendation:
Three switches on
method_type, growing with every new payment method → Strategy pattern.interface PaymentMethod { void process(Payment p); ValidationResult validate(Payment p); void refund(Payment p); } class CreditCard implements PaymentMethod { ... } class PayPal implements PaymentMethod { ... }New payment method → one new class, zero edits to existing switches.
Counter-check: Do
process/validate/refundalways change together when a method is added? Ifvalidateis actually the same for 4 of 5 methods, Strategy will force you to duplicate it. Consider: Strategy forprocess/refund, a singlevalidatewith a small type check.
## Symptom
<the structural problem — what hurts>
## Pattern fit
<pattern> — <why it matches this specific symptom>
## Or maybe just…
<simpler alternative if one exists — and when to prefer it>
## Sketch
<minimal code showing the pattern applied to THIS case, not a textbook example>
## When NOT to
<conditions under which this recommendation would be wrong>47d56bb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.