Design Patterns

Sefism.

Chapter 02

Creational patterns

The five patterns that decide how objects get created, so calling code does not depend on concrete classes or messy constructors.

Factory Method

Also called virtual constructor, factory

What
Intent: let a method decide which class to instantiate, so callers ask for "a transport" without naming the class.
Why
When: the exact type depends on configuration, input or subclass, and you want one place to change it.
TypeScript
interface Payment { pay(amount: number): void; }

function createPayment(kind: 'card' | 'wallet'): Payment {
  switch (kind) {
    case 'card': return new CardPayment();
    case 'wallet': return new WalletPayment();
  }
}

Watch out

A factory that grows a huge switch touched by every feature; register creators in a map instead.

Abstract Factory

Also called kit, family of objects

What
Intent: an interface for creating whole families of related objects, with one concrete factory per family.
Why
When: products must match each other, such as light and dark UI widgets or one cloud provider's storage and queue clients.
TypeScript
interface UiFactory {
  button(): Button;
  dialog(): Dialog;
}
class DarkUi implements UiFactory { /* dark parts */ }
class LightUi implements UiFactory { /* light parts */ }

const ui: UiFactory =
  prefersDark ? new DarkUi() : new LightUi();

Builder

Also called fluent builder, step builder

What
Intent: construct a complex object step by step, separating how it is assembled from what it ends up as.
Why
When: a constructor would take many optional parameters, or construction needs validation before the object exists.
TypeScript
const req = new RequestBuilder('https://api.site.pk/users')
  .method('POST')
  .header('Authorization', token)
  .json({ name: 'Sara' })
  .timeout(5000)
  .build();

Watch out

Adding a builder for objects with two fields; named arguments or an options object are simpler.

Prototype

Also called clone

What
Intent: create new objects by copying an existing, configured instance instead of building from scratch.
Why
When: setup is expensive or the exact class is unknown to the caller, such as duplicating shapes in an editor.
TypeScript
interface Shape { clone(): Shape; }

class Circle implements Shape {
  constructor(public r: number, public color: string) {}
  clone() { return new Circle(this.r, this.color); }
}

Watch out

Shallow copies that share nested objects, so editing the copy changes the original.

Singleton

Also called single instance

What
Intent: ensure a class has exactly one instance and give global access to it.
Why
When: one shared resource, such as a configuration object or a connection pool, must not be duplicated.
TypeScript
// In JS and TS a module is already a single instance
export const config = loadConfig();

// Classic form
class Registry {
  private static instance?: Registry;
  static get() { return (this.instance ??= new Registry()); }
}

Watch out

Using singletons as hidden global state, which makes tests order-dependent; pass the instance in instead.

02 · Creational patterns2 / 9