Design Patterns Interview Questions

Creational

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());
  }
}
Creational

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');
}
Behavioral

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} }
Behavioral

Observer

Publish/subscribe: subjects notify observers of changes. RxJS/EventEmitter implement this.

Structural

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));
}
Structural

Adapter

Convert one interface to another expected by clients (e.g., wrap a legacy API to match a new interface).

Creational

Builder

Construct complex objects step-by-step with a fluent API; separates construction from representation.

Structural

Proxy

Provide a stand-in to control access to a real object (caching, lazy-load, remote access).

Structural

Facade

Simplify a complex subsystem behind a unified interface, reducing coupling.

Structural

Composite

Treat individual objects and compositions uniformly (tree structures of components).

Behavioral

Command

Encapsulate requests as objects, allowing queuing, logging, and undo/redo.

Behavioral

Template Method

Define the skeleton of an algorithm, deferring steps to subclasses for customization.