| name | implementation-design-patterns |
| description | Implementation guide for the 22 Gang of Four design patterns in TypeScript, distilled from refactoring.guru. Use this skill when writing, refactoring, or reviewing TypeScript that exhibits a pattern-shaped problem โ class-explosion from inheritance, conditionals switching on type, tight coupling to concrete classes, tree-shaped models, runtime algorithm selection, undo/redo, snapshot-and-restore, state-dependent behavior, subscriber notification, or hiding subsystem complexity. Each pattern entry includes intent, problem, solution, applicability (when to use AND when NOT to use), a runnable TypeScript example, implementation steps, pros/cons, and relations to sibling patterns. Trigger even when no pattern is named โ cues like "class getting unwieldy," "giant switch," "swap implementations at runtime," "combinatorial subclasses," "need undo," or "traverse a tree" are pattern-shaped. Covers all 5 Creational, 7 Structural, and 10 Behavioral GoF patterns. |
TypeScript Design Patterns Best Practices (Refactoring Guru)
Implementation reference for the 22 Gang of Four design patterns in TypeScript, distilled from refactoring.guru. Each of the 22 pattern files across 3 categories captures intent, problem, solution, applicability, a runnable TypeScript example, implementation steps, pros/cons, and relations to sibling patterns.
The patterns are a vocabulary for structural decisions, not a prescription. Reach for a pattern only when its applicability criteria match the problem at hand โ every pattern entry includes a When NOT to Use section to guard against over-engineering.
When to Apply
- Refactoring a class that has grown unwieldy via inheritance โ combinatorial subclasses, conditional branching on type, or a "god class" with many responsibilities
- Designing a new module whose collaborators are not yet fixed โ you want to keep the interface stable while implementations vary
- Integrating an incompatible third-party API, library, or legacy class into existing code
- Modeling a tree-shaped domain (file systems, organization charts, expression ASTs, UI component trees) where leaves and branches must be treated uniformly
- Adding cross-cutting behavior at runtime โ logging, caching, access control, decoration โ without subclassing
- Selecting an algorithm or behavior variant at runtime based on configuration, user input, or environmental conditions
- Implementing undo/redo, history snapshots, transactional rollback, or scheduling/queueing of operations
- Coordinating many objects whose direct mutual references have become tangled โ a hub that brokers communication
- Notifying many subscribers when something changes โ event systems, reactive data flows
- Reviewing code that smells like a pattern is implicit (large switch on
kind, parallel class hierarchies, identical algorithm skeletons across siblings) โ make it explicit
Rule Categories
| # | Category | Impact | Patterns | When to reach for this group |
|---|
| 1 | Creational | HIGH | 5 | Object construction is non-trivial, varies by configuration, or risks tight coupling to concrete classes |
| 2 | Structural | HIGH | 7 | Composing classes/objects into larger structures while keeping parts substitutable |
| 3 | Behavioral | HIGH | 10 | Distributing responsibility and defining how objects collaborate at runtime |
How to Use
- Recognize the shape. Read the Quick Reference below and identify which pattern's intent matches your problem. Most pattern-shaped problems sound like one of the listed phrases.
- Read the pattern reference. Open
references/{category}-{pattern}.md. Confirm intent, then read Applicability and When NOT to Use before adopting.
- Adapt the example. The TypeScript example uses pedagogical names (
ConcreteStrategyA, Receiver). Rename to domain terms before merging.
- Check the relations. Each entry ends with Related Patterns โ siblings worth considering for the same problem.
Quick Reference
1. Creational Patterns (object instantiation)
creational-factory-method โ Subclasses decide which concrete product to create. "I need to add new product types without touching the creator code." โ HIGH
creational-abstract-factory โ Produce families of related objects together. "My code must work with multiple matching variants (chair+sofa+table) and shouldn't mix families." โ MEDIUM-HIGH
creational-builder โ Construct complex objects step by step. "My constructor has 10+ parameters or I have a telescoping-constructor smell." โ HIGH
creational-prototype โ Clone objects through their own clone() method. "I need to copy objects without depending on their concrete class." โ MEDIUM
creational-singleton โ Guarantee a single shared instance with a global access point. "I need exactly one instance of this class โ config, registry, pool." โ MEDIUM
2. Structural Patterns (composition)
structural-adapter โ Translate one interface to another. "I need to use a library whose API doesn't match what my code expects." โ HIGH
structural-bridge โ Split abstraction from implementation so they can vary independently. "I have two orthogonal dimensions and the subclass count is exploding." โ MEDIUM
structural-composite โ Treat individual objects and compositions uniformly. "I have a tree (folders/files, groups/items, components/children) and want one interface for leaves and branches." โ HIGH
structural-decorator โ Wrap an object to add behavior without subclassing. "I want to layer behaviors (logging + caching + auth) on the same interface at runtime." โ HIGH
structural-facade โ Expose a simple interface over a complex subsystem. "My client code is tangled in initialization and orchestration of a third-party library." โ HIGH
structural-flyweight โ Share common state across many objects to save memory. "I'm spawning millions of similar objects and running out of RAM." โ LOW-MEDIUM
structural-proxy โ Substitute for another object to control access. "I need lazy loading, access control, caching, or logging without touching the real subject." โ MEDIUM-HIGH
3. Behavioral Patterns (collaboration)
behavioral-chain-of-responsibility โ Pass a request along a chain of handlers. "I have a pipeline of validation / auth / parsing checks and want to add or reorder them dynamically." โ MEDIUM-HIGH
behavioral-command โ Turn a request into a stand-alone object. "I need undo/redo, queueing, scheduling, macro recording, or to decouple invoker from receiver." โ HIGH
behavioral-iterator โ Traverse a collection without exposing its representation. "I want clients to walk a structure without knowing if it's a list, tree, or graph." โ HIGH
behavioral-mediator โ Centralize communication among components in a single hub. "My form fields all reference each other directly and the coupling is unmanageable." โ MEDIUM
behavioral-memento โ Capture and restore an object's state without breaking encapsulation. "I need snapshots for undo/redo or transactional rollback." โ LOW-MEDIUM
behavioral-observer โ Notify dependent objects when state changes. "Many objects need to react when one object changes โ events, reactive UI, pub/sub." โ CRITICAL
behavioral-state โ Alter behavior when internal state changes. "My class is a state machine with massive conditionals branching on a status field." โ MEDIUM-HIGH
behavioral-strategy โ Make algorithms interchangeable at runtime. "I have multiple algorithms (sort, route, pay, compress) and want to pick one without conditionals." โ HIGH
behavioral-template-method โ Fix an algorithm's skeleton in a base class; subclasses override steps. "Several classes share the same algorithm structure with minor step differences." โ MEDIUM
behavioral-visitor โ Add operations to an object structure without modifying the classes. โ
How to Choose Between Similar Patterns
Several patterns share a structural shape but solve different problems. Read each pattern's Related Patterns section, then apply these distinctions:
- Adapter vs. Facade vs. Proxy vs. Decorator โ all four wrap a target. Adapter changes the interface. Facade simplifies a subsystem. Proxy keeps the interface and controls access/lifecycle. Decorator keeps the interface and adds behavior recursively.
- Strategy vs. State โ both swap a delegated object. Strategy objects are independent; the client picks one. State objects know each other and trigger transitions on the context.
- Strategy vs. Template Method โ both vary parts of an algorithm. Strategy uses composition (swap at runtime). Template Method uses inheritance (fixed at compile time).
- Factory Method vs. Abstract Factory vs. Builder โ Factory Method returns one product through a single method. Abstract Factory returns a family of related products through several methods. Builder assembles one complex product step by step.
- Composite vs. Decorator โ both wrap children recursively. Composite sums or aggregates child results. Decorator adds responsibilities and passes through.
- Chain of Responsibility vs. Command vs. Mediator vs. Observer โ all connect senders and receivers. CoR passes a request along a chain. Command makes the request a first-class object. Mediator centralizes mutual communication. Observer establishes one-publisher-to-many-subscribers notification.
Related Skills
implementation-functional-patterns โ TypeScript's functional answer (HOFs, lambdas, pipelines, streams, composition) for problems where this catalog reaches for a class. Most Strategy / Iterator / Command / Chain-of-Responsibility / Decorator / Template-Method shapes have a lighter functional form in idiomatic TS; consult it before introducing a new class hierarchy.
References
- Refactoring Guru โ Design Patterns Catalog
- Refactoring Guru โ TypeScript Examples
- Refactoring Guru โ Creational Patterns
- Refactoring Guru โ Structural Patterns
- Refactoring Guru โ Behavioral Patterns