Skip to content

@tank/design-patterns

1.0.0
Skill

Description

JavaScript and TypeScript design patterns catalog. Covers GoF creational, structural, and behavioral patterns (Factory, Singleton, Observer, Strategy, Command, Decorator, Adapter, Proxy, State, Builder, Facade, Iterator) plus modern JS/TS patterns (Module, Provider, Middleware, Pipeline, Repository, Pub/Sub, Plugin/Hook). Synthesizes Gamma et al., Freeman, Osmani, Fowler, Vlissides..

Download
Verified
tank install @tank/design-patterns

Design Patterns

Structural solutions for recurring problems in JavaScript and TypeScript applications.

Core Philosophy

  1. Patterns are tools, not goals. Apply a pattern to solve a specific problem. If the problem does not exist, the pattern is overhead.
  2. Favor composition over inheritance. JS/TS excels at object composition, closures, and higher-order functions. Most GoF inheritance hierarchies collapse into simpler functional forms.
  3. Match the pattern to the language. A Java-style Singleton is an anti-pattern in JS modules. Adapt patterns to closures, first-class functions, Proxies, and ES module scope.
  4. Prefer the simplest pattern that solves the problem. If a function suffices, do not introduce a class hierarchy. Escalate complexity only when requirements demand it.
  5. Name the pattern in your code. When you use a pattern, name it explicitly (e.g., UserFactory, RetryStrategy). This communicates intent to future readers.

Pattern Selection Decision Tree

Problem SignalRecommended PatternCategory
Need to create objects without specifying exact classFactory / Abstract FactoryCreational
Complex object with many optional fieldsBuilderCreational
Need exactly one shared instanceModule Scope / SingletonCreational
Need to clone expensive-to-create objectsPrototypeCreational
Incompatible interface between two systemsAdapterStructural
Need to add behavior without modifying sourceDecoratorStructural
Simplify a complex subsystem APIFacadeStructural
Intercept or control access to an objectProxyStructural
Many similar objects consuming too much memoryFlyweightStructural
One-to-many notifications on state changeObserver / Pub-SubBehavioral
Swap algorithms at runtimeStrategyBehavioral
Encapsulate actions as objects (undo/redo, queues)CommandBehavioral
Object behavior changes based on internal stateStateBehavioral
Decouple many-to-many communicationMediatorBehavioral
Sequential processing with bail-outChain of ResponsibilityBehavioral
Request/response pipeline with transformsMiddleware / PipelineModern
Extensible system with third-party hooksPlugin / HookModern
Decouple data access from business logicRepositoryModern
Cross-cutting shared context (React, DI)ProviderModern

Quick-Start: Common Problems

"I need to create objects but the type varies at runtime"

  1. Start with Factory Method for a single product family.
  2. Escalate to Abstract Factory when multiple related families exist. -> See references/creational-patterns.md

"I need to add logging/caching/retry without changing existing code"

  1. Use Decorator for wrapping individual instances.
  2. Use Proxy for transparent interception (access control, lazy loading). -> See references/structural-patterns.md

"I have complex conditional logic that changes based on state"

  1. Use Strategy if the algorithm is selected once per operation.
  2. Use State if the object transitions between modes over its lifetime. -> See references/behavioral-patterns.md

"I need a request pipeline (auth, validation, logging, handler)"

  1. Use Middleware/Pipeline for linear request processing.
  2. Use Chain of Responsibility if handlers can stop propagation. -> See references/modern-patterns.md

"I am not sure which pattern fits my problem"

  1. Consult the decision tree above.
  2. Read the anti-patterns section below to rule out misapplications. -> See references/pattern-selection-guide.md

Anti-Patterns: Pattern Misuse

MisuseSymptomRemedy
Singleton for dependency sharingHidden global state, untestableUse Dependency Injection
Factory for one concrete typeUnnecessary indirectionUse new directly
Observer with 20+ listenersSpaghetti event flow, debug hellUse Mediator or explicit wiring
Decorator stacking 5+ layersUnreadable, hard to debugFlatten into a single composed function
Strategy with one strategyOver-engineeringUse a plain function
Abstract Factory for 1 productPremature abstractionUse simple Factory Method
Builder for 2-field objectsCeremony without benefitUse plain constructor or object literal

Pattern Categories At a Glance

CategoryPatternsFocus
CreationalFactory, Abstract Factory, Builder, Prototype, SingletonObject creation mechanisms
StructuralAdapter, Decorator, Facade, Proxy, FlyweightObject composition and interface design
BehavioralObserver, Strategy, Command, State, Mediator, Chain of Responsibility, IteratorCommunication and responsibility distribution
Modern JS/TSModule, Provider, Middleware, Pipeline, Repository, Unit of Work, Pub/Sub, Plugin/HookPatterns native to JS/TS ecosystems

Reference Index

FileContents
references/creational-patterns.mdFactory, Abstract Factory, Builder, Prototype, Singleton — intent, JS/TS implementation, when to use, when not to use
references/structural-patterns.mdAdapter, Decorator, Facade, Proxy, Flyweight — intent, JS/TS implementation, real-world examples
references/behavioral-patterns.mdObserver, Strategy, Command, State, Mediator, Chain of Responsibility, Iterator — intent, JS/TS implementation
references/modern-patterns.mdModule, Provider, Middleware/Pipeline, Repository, Unit of Work, Pub/Sub, Plugin/Hook — JS/TS-native patterns
references/pattern-selection-guide.mdDecision matrices, pattern combination recipes, migration paths, complexity comparison, when-not-to-use tables

Command Palette

Search packages, docs, and navigate Tank