Module 4 / Behavioral patterns
Module 4 · Core Patterns

Behavioral patterns

Define how objects communicate, distribute responsibilities, and encapsulate algorithms.

0/11 lessons

Observer

Learn

The Observer establishes a one-to-many dependency: when the subject changes state, all registered observers are notified and updated automatically. The subject doesn't know the concrete types of its observers — only that they implement a notification interface.

This is the foundation of event-driven architectures, reactive programming, and pub/sub systems. DOM event listeners, RxJS observables, Redux store subscriptions, and Vue's reactivity system are all Observer variants.

class EventEmitter { private listeners: Map<string, Function[]> = new Map(); on(event: string, fn: Function) { this.listeners.get(event)?.push(fn) ?? this.listeners.set(event, [fn]); } emit(event: string, ...args: unknown[]) { this.listeners.get(event)?.forEach(fn => fn(...args)); } }
Observers can cause cascading updates and memory leaks if subscriptions aren't cleaned up. Always unsubscribe when the observer's lifecycle ends.
Practice
Loading…
Recall0/1
Recall

What problem does the Observer pattern solve?

Strategy

Learn

The Strategy extracts varying algorithms into separate classes that share a common interface. The context holds a reference to a strategy and delegates to it — swapping strategies changes behavior without modifying the context.

This replaces conditional logic (if/else, switch) with polymorphism. Instead of a giant function with branches for each algorithm, each branch becomes its own class implementing the strategy interface.

interface SortStrategy { sort(data: number[]): number[]; } class QuickSort implements SortStrategy { sort(d) { … } } class MergeSort implements SortStrategy { sort(d) { … } } class DataProcessor { constructor(private strategy: SortStrategy) {} process(data: number[]) { return this.strategy.sort(data); // ← delegates to strategy } }
Strategy is one of the most practical patterns day-to-day. Anytime you see a function with multiple algorithmic branches selected by a parameter, that's a candidate for extraction into strategies.
Practice
Loading…
Recall0/1
Recall

What does the Strategy pattern replace?

Command

Learn

The Command encapsulates a request as an object — bundling the action, its parameters, and the receiver into a single callable entity. This decouples the invoker (who triggers the action) from the receiver (who performs it).

Because commands are objects, you can queue them, log them, serialize them, support undo/redo, or schedule them for later execution. Text editors, task schedulers, and transactional systems rely heavily on this pattern.

interface Command { execute(): void; undo(): void; } class PasteCommand implements Command { constructor(private editor: Editor, private clipboard: string) {} execute() { this.editor.insert(this.clipboard); } undo() { this.editor.delete(this.clipboard.length); } } // Invoker doesn't know what the command does history.push(command); command.execute();
Command turns actions into data. Once an operation is an object, you gain queuing, undo, replay, and macro capabilities almost for free.
Practice
Loading…
Recall0/1
Recall

What capability does Command unlock that direct method calls cannot?

Iterator

Learn

The Iterator provides a way to traverse a collection without exposing its internal structure (array, linked list, tree, hash map). The client gets a uniform traversal interface regardless of how the collection stores its elements.

Modern languages have largely absorbed this pattern into the language itself: JavaScript's `for...of`, Python's `iter()`/`next()`, Java's `Iterable`, C#'s `IEnumerable`. You rarely implement Iterator from scratch anymore — but understanding it explains why these constructs work.

// Modern JS: Iterator protocol built-in const range = { from: 1, to: 5, [Symbol.iterator]() { let current = this.from; return { next: () => current <= this.to ? { value: current++, done: false } : { done: true } }; } }; for (const n of range) console.log(n); // 1, 2, 3, 4, 5
Even though you won't hand-roll iterators often, recognizing the pattern helps you understand generators, async iteration, streams, and custom iterable protocols.
Practice
Loading…
Recall0/1
Recall

Why has the Iterator pattern been largely absorbed into modern programming languages?

Chain of Responsibility

Learn

The Chain of Responsibility pattern lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler.

It is heavily used in UI event handling and middleware pipelines (like Express.js).

Recall0/1
Recall

Where is the Chain of Responsibility pattern most commonly seen in modern web development?

Interpreter

Learn

The Interpreter pattern defines a representation for a grammar as well as a mechanism to understand and execute it.

It is rarely used for complex languages (where parsers and ASTs are better), but useful for simple configuration languages or regular expressions.

Recall0/1
Recall

For which scenario is the Interpreter pattern most appropriate?

Mediator

Learn

The Mediator pattern reduces chaotic dependencies between objects by forcing them to communicate through a central mediator object.

This prevents a tangled web of mutually dependent components, heavily utilized in UI dialogs and chat rooms.

Recall0/1
Recall

How does the Mediator pattern improve coupling?

Memento

Learn

The Memento pattern lets you save and restore the previous state of an object without revealing the details of its implementation.

It is the standard pattern for implementing 'Undo/Redo' functionality.

Recall0/1
Recall

What is the primary use case for the Memento pattern?

State

Learn

The State pattern lets an object alter its behavior when its internal state changes. It appears as if the object changed its class.

It is a cleaner, object-oriented alternative to massive `switch` statements governing state machine transitions.

Recall0/1
Recall

The State pattern is essentially an object-oriented replacement for what?

Template Method

Learn

The Template Method pattern defines the skeleton of an algorithm in a base class but lets subclasses override specific steps of the algorithm without changing its structure.

It leverages inheritance to provide a rigid algorithm framework with customizable hooks.

Recall0/1
Recall

How does Template Method differ from Strategy?

Visitor

Learn

The Visitor pattern lets you separate algorithms from the objects on which they operate. It allows you to add new behaviors to a class hierarchy without altering any existing code.

It relies on a technique called 'Double Dispatch' and is heavily used in compilers for traversing Abstract Syntax Trees (AST).

Recall0/1
Recall

Which programming technique makes the Visitor pattern possible in languages that don't support it natively?