099
LVL 04 — SENIOR-IN-TRAININGSESSION 099DAY 99

DESIGN PATTERNS

🎫 PIXELCRAFT-085
📚Learning / Refactor | 🟡 Medium | Priority: 🟡 Medium

Code review feedback: "You've built several design patterns without knowing their names." Identify them. Name them. Understand when to use each. You already know these — now learn the vocabulary.
CONCEPTS.UNLOCKED
👁️
Observer Pattern
When something changes, notify everyone interested. addEventListener, React state subscriptions, WebSocket event handlers, useEffect. You've used this in nearly every session since session 1.
⌨️
Command Pattern
Encapsulate an action as an object. { type: 'APPLY_FILTER', payload: {...} } — Redux/useReducer actions. Each command can be stored, replayed, undone. Your undo system IS the command pattern.
🏭
Factory Pattern
Create objects without specifying exact class. createFilter('sepia') returns the right filter object. Component factories, API response builders. Hide creation complexity behind a simple function call.
1️⃣
Singleton Pattern
One instance, shared everywhere. Your database connection, Redis client, logger, WebSocket instance. Created once, imported everywhere. Global state with controlled access.
🔀
Strategy Pattern
Swap algorithms at runtime. Cache strategies (cache-first, network-first), sort comparators, filter algorithms. Same interface, different behavior. Pass a function → change the strategy.
⛓️
Middleware / Chain of Responsibility
Pass request through a chain of handlers. Express: logger → auth → validate → handler → error. Each middleware decides: handle it, pass it along, or reject it. Your entire Express app is this pattern.
HANDS-ON.TASKS
01
Identify Patterns in PixelCraft
// Patterns already in YOUR code: Observer: addEventListener, useEffect subs, WebSocket events, EventEmitter Command: useReducer actions: { type: 'SET_FILTER', payload: {...} } Undo stack = command history Factory: createFilterSlider(name, min, max) apiGet<T>(path) — typed API factory Singleton: Single DB connection Single Redis client, single logger Strategy: Cache: cache-first vs network-first Filters: different algorithms, same interface Middleware: Express: logger → auth → validate → handler → errorHandler Pipeline: Filter pipeline: original → brightness → contrast → sepia
02
Formalize: Typed EventEmitter
class EventEmitter< T extends Record<string, any> > { private listeners = new Map<keyof T, Set<Function>>(); on<K extends keyof T>( event: K, callback: (data: T[K]) => void ) { if (!this.listeners.has(event)) this.listeners.set(event, new Set()); this.listeners.get(event)! .add(callback); // Return unsubscribe function return () => this.listeners.get(event)! .delete(callback); } emit<K extends keyof T>( event: K, data: T[K] ) { this.listeners.get(event) ?.forEach(cb => cb(data)); } } // Usage — fully typed: type EditorEvents = { 'filter-changed': { name: string; value: number }; 'image-loaded': { width: number; height: number }; 'export-complete': { filename: string }; }; const bus = new EventEmitter<EditorEvents>(); bus.on('filter-changed', ({ name, value }) => { // TS knows: name is string, // value is number console.log(name, value); }); bus.emit('filter-changed', { name: 'brightness', value: 50 });
03
Strategy Pattern: Filter Algorithms
// Strategy: same interface, // swappable behavior interface FilterStrategy { name: string; apply( imageData: ImageData ): ImageData; } const sepiaFilter: FilterStrategy = { name: 'sepia', apply(imageData) { return applyColorMatrix( imageData, SEPIA_MATRIX); }, }; const blurFilter: FilterStrategy = { name: 'blur', apply(imageData) { return applyConvolution( imageData, BLUR_KERNEL); }, }; // The editor doesn't care WHICH // filter — it just calls .apply() function applyFilter( image: ImageData, strategy: FilterStrategy ): ImageData { return strategy.apply(image); } // Swap strategy at runtime: applyFilter(image, sepiaFilter); applyFilter(image, blurFilter);
04
Anti-Patterns: When NOT to Use
// ❌ OVER-ENGINEERING: // Using a Factory + Strategy + Observer // + Command pattern for a simple // utility function // When in doubt, use a function. // ❌ Singleton abuse: // Making everything global. // Only singleton what truly needs // to be shared (DB connection, logger). // ❌ Pattern matching: // "I need to use Observer here" // → Wrong. Start with the problem, // discover the pattern fits. // ✅ The right approach: // 1. Write simple code // 2. Notice a recurring problem // 3. Recognize a pattern applies // 4. Apply it // NOT: "which pattern should I use?"
05
Close the Ticket
git switch -c refactor/PIXELCRAFT-085-design-patterns git add src/ docs/patterns.md git commit -m "Document and formalize design patterns (PIXELCRAFT-085)" git push origin refactor/PIXELCRAFT-085-design-patterns # PR → Review → Merge → Close ticket ✅
CS.DEEP-DIVE

The "Gang of Four" cataloged 23 design patterns in 1994.

These are solutions to recurring software design problems. They transcend languages. The real skill isn't memorizing patterns — it's recognizing when a problem matches one.

// GoF pattern categories:

Creational (how objects are made)
  Factory, Singleton, Builder,
  Prototype, Abstract Factory

Structural (how objects compose)
  Adapter, Decorator, Facade,
  Proxy, Composite, Bridge

Behavioral (how objects interact)
  Observer, Strategy, Command,
  Iterator, State, Template Method,
  Chain of Responsibility

// In JavaScript/TypeScript:
// Many patterns simplify to
// "pass a function."
// Strategy = pass a callback.
// Observer = event listeners.
// Factory = return an object.
//
// You've built them organically.
// Now you have the vocabulary.
"Patterns Lab"
[A]Implement the Decorator pattern: create withLogging(handler) and withAuth(handler) higher-order functions for Express routes. Stack them: withLogging(withAuth(uploadHandler)). Compare to middleware.
[B]Implement the State pattern: the editor has modes (select, draw, crop, text). Each mode handles mouse events differently. Instead of switch statements, each mode is a state object with its own handlers.
[C]Research: "Design Patterns: Elements of Reusable Object-Oriented Software" (1994). Read chapter summaries. Which patterns are still relevant in modern JS? Which have been replaced by language features (closures, first-class functions)?
REF.MATERIAL
ARTICLE
Refactoring Guru
The best visual guide to all 23 GoF patterns: illustrations, code examples in multiple languages, real-world analogies. Bookmark this.
PATTERNSVISUALESSENTIAL
VIDEO
Fireship
Quick overview of the most-used design patterns with JavaScript examples: Singleton, Observer, Factory, Strategy, and more.
PATTERNSQUICK
ARTICLE
Lydia Hallie & Addy Osmani
Modern JavaScript and React patterns: render props, hooks, compound components, HOCs, and more. Patterns for the modern web.
MODERNREACTESSENTIAL
ARTICLE
Dov Amir
Curated list of design pattern resources across languages: GoF patterns, cloud patterns, microservice patterns, and domain-driven design.
PATTERNSCURATED
VIDEO
Jack Herrington
Practical design patterns in TypeScript: Strategy, Observer, Factory, Decorator. Real-world implementations, not textbook theory.
TYPESCRIPTPRACTICAL
// LEAVE EXCITED BECAUSE
You already know design patterns — you've been building them for 90+ sessions without knowing their names. Now you have the vocabulary that every tech interview expects and every architecture discussion uses.