Design Patterns
Overview
Challenges
-
Module Pattern Challenge
Refactor exposed global state into an encapsulated module with a clean public API.
-
Observer Pattern Challenge
Replace hardcoded dependents with a subscribe/notify contract, and enforce the full listener lifecycle.
-
Factory Pattern Challenge
Centralise branching construction logic into one factory so callers depend on a shared interface, not concrete implementations.
-
Strategy Pattern Challenge
Extract interchangeable algorithms from a branching context so each variant is injectable, testable, and swappable at runtime.
-
Decorator Pattern Challenge
Layer cross-cutting behavior onto a base function by wrapping it — without editing the core or duplicating boilerplate.
-
Registry Pattern Challenge
Replace hardcoded lookup tables and branching dispatch with a register/resolve registry so producers and consumers decouple across module boundaries.
-
Orchestrator Pattern Challenge
Extract workflow sequencing into one orchestrator function so independent steps stay decoupled, testable, and readable in order.
-
State Machine Pattern Challenge
Replace overlapping boolean flags and ad-hoc transition logic with explicit states and events so invalid combinations become impossible.
-
Mediator Pattern Challenge
Route peer events through a central mediator so colleagues stop importing each other and new participants plug in without editing existing modules.
-
Command Pattern Challenge
Encapsulate actions as apply/revert command objects with an invoker history stack so undo, redo, and shared toolbar shortcuts become possible.
-
Adapter Pattern Challenge
Centralise interface translation in an adapter so clients keep a stable target API while legacy or third-party adaptees stay unchanged.
-
Proxy Pattern Challenge
Introduce a stand-in with the same interface as the real subject to control lazy loading, caching, or access — without changing callers.
Notes
Patterns
-
Module Pattern
Encapsulate related code behind a public API while hiding private state.
-
Factory Pattern
Centralize object creation behind a function or method so callers depend on an interface, not concrete constructors.
-
Observer Pattern
A one-to-many subscription: a Subject notifies registered Observers whenever its state changes.
-
Strategy Pattern
Encapsulate interchangeable algorithms behind one interface so the caller picks behavior at runtime without branching.
-
Decorator Pattern
Wrap an object to add behavior at runtime while keeping the same interface — stack layers without subclass explosion.
-
Registry Pattern
A central map that associates keys with registered values so callers resolve by name without importing concrete implementations.
-
Orchestrator Pattern
A single function coordinates a sequence of independent steps in order — each step does its own work; the Orchestrator owns the flow.
-
State Machine Pattern
Model UI and application behaviour as named states with explicit transitions — making impossible states impossible.
-
Mediator Pattern
A central coordinator routes messages between peers so colleagues never reference each other directly.
-
Command Pattern
Encapsulate a request as an object so you can queue it, log it, undo it, or replay it — without the caller knowing how it runs.
-
Adapter Pattern
Translate one interface into another so existing code can work with a library or API it was not written for — without changing either side.
-
Proxy Pattern
Stand in for another object with the same interface — control access through lazy loading, caching, validation, or remote delegation without changing callers.