Singleton
Ensures one instance globally. In JS/TS, export a module-level instance. Beware of hidden dependencies and testing complications.
class Config {
private static _i: Config;
private constructor() {}
static get instance() {
return this._i ?? (this._i = new Config());
}
}Factory
Create objects via an interface; decouple creation from usage.
function loggerFactory(type: 'json'|'text') {
if (type === 'json') return () => console.log(JSON.stringify({msg:'hi'}));
return () => console.log('hi');
}Strategy
Swap algorithms at runtime via a common interface.
interface Sorter { sort(a:number[]):number[] }
class QuickSort implements Sorter { sort(a){/*...*/return a} }
class MergeSort implements Sorter { sort(a){/*...*/return a} }Observer
Publish/subscribe: subjects notify observers of changes. RxJS/EventEmitter implement this.
Decorator
Wrap objects to add behavior without modifying original class.
function withCache(fn: Function){
const cache = new Map();
return (x:any)=> cache.has(x)?cache.get(x):(cache.set(x, fn(x)), cache.get(x));
}Adapter
Convert one interface to another expected by clients (e.g., wrap a legacy API to match a new interface).
Builder
Construct complex objects step-by-step with a fluent API; separates construction from representation.
Proxy
Provide a stand-in to control access to a real object (caching, lazy-load, remote access).
Facade
Simplify a complex subsystem behind a unified interface, reducing coupling.
Composite
Treat individual objects and compositions uniformly (tree structures of components).
Command
Encapsulate requests as objects, allowing queuing, logging, and undo/redo.
Template Method
Define the skeleton of an algorithm, deferring steps to subclasses for customization.