CtrlK
BlogDocsLog inGet started
Tessl Logo

design-pattern-suggestor

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-suggestor
What are skills?

90

Quality

87%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SKILL.md
Review
Evals

Design Pattern Suggestor

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.

Problem → pattern (NOT pattern → problem)

Start from the symptom. The pattern is the answer; the problem is the question.

SymptomPatternOr maybe just…
Switch on type code, same switch in 3+ placesStrategy / State…one switch if it's only in one place
Constructor has 8 parameters, 5 are optionalBuilder…keyword arguments with defaults
Need exactly one of a thing, globallySingleton…a module-level variable (in Python/JS)
Class hierarchy × orthogonal dimension = class explosionDecorator / Bridge…composition with a field
Creating objects, but which concrete type depends on runtime dataFactory…a dict {key: constructor} — often enough
Many objects need to know when one object changesObserver…a callback list — that IS observer
Different interface than what you have, can't change either sideAdapterUsually correct, rarely over-applied
Need undo, or need to queue/log/serialize operationsCommandUsually correct
Traversing a composite structure uniformlyVisitor / Iterator…if the structure rarely changes, just recurse

The "or maybe just…" column matters

Most pattern misuse is applying GoF ceremony where the language already gives you the mechanism for free:

  • Strategy in Python: Functions are first-class. strategies = {"a": fn_a, "b": fn_b} is the pattern.
  • Singleton in Python/JS: A module IS a singleton. import config — done.
  • Observer in anything with events: addEventListener, signals, Rx — the pattern is built into the runtime.
  • Iterator: Every modern language has 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.

Anti-pattern detection

Sometimes the finding is "you're using a pattern wrong":

Anti-patternSymptom
Singleton-as-globalSingleton exists to avoid passing a dependency — hidden coupling, untestable
Factory-for-oneUserFactory.create() returns new User() — the factory adds nothing
Observer soup10 observers, firing order matters, some observers trigger other observers — you've built an implicit state machine
Premature StrategyOne concrete strategy. The interface exists "in case we need another." → speculative generality
Visitor on a stable hierarchyThe hierarchy never changes; visitor's indirection buys nothing

Worked example

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/refund always change together when a method is added? If validate is actually the same for 4 of 5 methods, Strategy will force you to duplicate it. Consider: Strategy for process/refund, a single validate with a small type check.

Do not

  • Do not suggest a pattern without stating the problem it solves here. "Use Factory" is cargo cult. "Use Factory because which concrete class depends on a config value you don't know at compile time" is a reason.
  • Do not apply Java-idiom patterns to languages that don't need them. Strategy in a language with first-class functions is just "pass a function."
  • Do not add a pattern for a problem you might have. One concrete class? No Strategy. One way to build it? No Builder. YAGNI.
  • Do not suggest Visitor unless the type hierarchy is closed and the operations are open. If you're adding types more often than operations, Visitor fights you.

Output format

## 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>
Repository
santosomar/general-secure-coding-agent-skills
Last updated
Created

Is this your skill?

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.