Day 02 Core Concepts

Structural Patterns

Structural patterns organize relationships between objects. Adapter wraps incompatible interfaces, Decorator adds behavior, and Facade simplifies complex subsystems.

~1 hour Hands-on Precision AI Academy

Today’s Objective

Structural patterns organize relationships between objects. Adapter wraps incompatible interfaces, Decorator adds behavior, and Facade simplifies complex subsystems.

Structural Patterns is one of the most important topics in Design Patterns in 5 Days. This lesson builds the foundation you need before moving to more advanced concepts — take time with each example and run the code yourself.

typescript
TYPESCRIPT
// Adapter — make incompatible interfaces work together
// Old payment interface
class OldPayPal { makePayment(amount: number, currency: string) { console.log(\`PayPal: \${amount} \${currency}\`); }
}

// New interface your app expects
interface PaymentProcessor { charge(cents: number): void;
}

// Adapter bridges the gap
class PayPalAdapter implements PaymentProcessor { constructor(private paypal: OldPayPal) {} charge(cents: number) { this.paypal.makePayment(cents / 100, 'USD'); }
}

const processor: PaymentProcessor = new PayPalAdapter(new OldPayPal());
processor.charge(4999); // PayPal: 49.99 USD
typescript
TYPESCRIPT
// Decorator — add behavior without subclassing
interface Logger { log(message: string): void;
}

class ConsoleLogger implements Logger { log(message: string) { console.log(message); }
}

class TimestampLogger implements Logger { constructor(private wrapped: Logger) {} log(message: string) { this.wrapped.log(\`[\${new Date().toISOString()}] \${message}\`); }
}

class PrefixLogger implements Logger { constructor(private wrapped: Logger, private prefix: string) {} log(message: string) { this.wrapped.log(\`\${this.prefix} \${message}\`); }
}

// Stack decorators
const logger = new PrefixLogger( new TimestampLogger(new ConsoleLogger()), '[INFO]');
logger.log('Server started');
// [INFO] [2026-04-10T...] Server started
typescript
TYPESCRIPT
// Facade — simplify a complex subsystem
class OrderFacade { constructor( private inventory: InventoryService, private payment: PaymentService, private shipping: ShippingService, private email: EmailService, ) {} async placeOrder(cart: Cart, card: CreditCard, address: Address) { await this.inventory.reserve(cart.items); await this.payment.charge(card, cart.total); const tracking = await this.shipping.dispatch(cart.items, address); await this.email.sendConfirmation(cart.userId, tracking); return tracking; }
}

Exercise: Refactor a Module Using These Patterns

  1. Find a function with 3+ different concerns
  2. Extract each concern into its own class
  3. Add an Adapter to wrap a third-party library
  4. Use a Facade to expose a simple API to callers
  5. Write tests against the Facade, not internals

Supporting Resources

Go deeper with these references.

Refactoring.Guru
Design Patterns Catalog Visual explanations of all 23 GoF patterns with examples in multiple languages.
GitHub
TypeScript Design Patterns Community collection of design pattern implementations in TypeScript.
O'Reilly
Head First Design Patterns The most approachable book-length treatment of the classic Gang of Four patterns.

Day 2 Checkpoint

Before moving on, make sure you can answer these without looking:

Continue To Day 3
Observer and Event Emitter