OOP Interview Prep
Design Patterns

What Are Design Patterns?

The GoF Blueprint Every Developer Should Know

LinkedIn Hook

Every senior developer interview eventually asks a version of the same question:

"Tell me about a design pattern you've used in a real project."

Most candidates name one. Singleton. Maybe Factory. Then they freeze when the follow-up comes: "Why did you choose that one specifically? What problem were you solving? What are the trade-offs?"

Design patterns are not vocabulary. They are solutions to recurring problems that engineers figured out, named, and documented so the rest of us don't have to rediscover them from scratch.

The Gang of Four published 23 of these solutions in 1994. Thirty years later, interviewers still use them to separate developers who understand structure from those who just write working code.

Lesson 8.1 covers what design patterns are, why they exist, how the three categories differ, and which six patterns this chapter will walk through in detail.

Read the full lesson -> [link]

#OOP #JavaScript #DesignPatterns #SoftwareEngineering #InterviewPrep


What Are Design Patterns? thumbnail


What You'll Learn

  • Why design patterns exist and what problem they were created to solve
  • Who the Gang of Four are and why their 1994 book still shapes interviews today
  • The three pattern categories (Creational, Structural, Behavioral) and what distinguishes each
  • The four-part structure of any pattern: name, problem, solution, and consequences
  • Which six patterns this chapter covers and why those six were chosen for interview preparation

The Analogy — Recipes vs Cooking From Scratch

Imagine you are a chef opening a new restaurant. You could invent every dish from scratch: figure out ratios, test temperatures, discover techniques through trial and error. Eventually you'd arrive at something that works. But you'd spend years reinventing what professional chefs already know.

Or you could start with proven recipes. Not rigid scripts, but structured starting points: a classic roux for thickening sauces, a beurre blanc for emulsification, a mise en place system for kitchen organization. Each recipe has a name (so you can discuss it with other chefs), a problem it solves (why you'd reach for it), a technique (how you apply it), and trade-offs (where it works and where it doesn't).

Design patterns are recipes for software structure. They are not code you copy. They are named, documented solutions to recurring structural problems that developers encounter when building object-oriented systems. You adapt them to your specific context, just like a chef adapts a recipe to the ingredients available.

The analogy breaks down here: a cooking recipe produces the same dish every time. A design pattern produces a different class structure every time, shaped by your domain. The pattern provides the logic, not the literal code.

[IMAGE: Split illustration — left side: a handwritten recipe card with structured sections (Ingredients, Method, Notes) labeled "Recipe"; right side: a UML-style class diagram with sections (Problem, Structure, Consequences) labeled "Pattern". Dark background #0a0a1a, neon green highlights on the pattern side - search terms: "recipe card vs blueprint software design pattern diagram"]


Why Do Design Patterns Exist?

Before patterns were documented, every developer working on a similar problem would solve it slightly differently, name it differently, and explain it differently to their team. There was no shared language for structural decisions, which made code reviews slower, onboarding harder, and architectural discussions filled with misunderstandings.

Design patterns solve three problems at once. First, they capture proven solutions so you don't spend time rediscovering what already works. Second, they give teams a shared vocabulary: saying "use the Strategy pattern here" communicates in two words what would otherwise take a paragraph of explanation. Third, they make intent visible in code — when a developer recognizes a pattern, they understand not just what the code does but why it was structured that way.

[UNIQUE INSIGHT]: Patterns are not about reducing lines of code. A pattern often adds more structure and more classes than a naive solution. The payoff is flexibility and clarity over time, not brevity right now. Candidates who describe patterns as "shortcuts" reveal they've only read the definition and never applied one under changing requirements.

[INTERNAL-LINK: why OOP structure matters for maintainability → Lesson 1.1: What is OOP?]


Who Are the Gang of Four?

The term "Gang of Four" refers to four software engineers — Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides — who published "Design Patterns: Elements of Reusable Object-Oriented Software" in 1994. The book documented 23 patterns drawn from real-world object-oriented codebases, primarily written in C++ and Smalltalk.

The book did not invent the patterns. It named and described patterns that experienced developers were already using without a common vocabulary. That naming is what made the book influential. Once a pattern has a name, teams can discuss, critique, and improve it. The 23 patterns in the book became the baseline that most OOP interviews still reference today.

It is worth noting that the book is 30 years old and was written before dynamic languages like JavaScript were common. Some patterns, like the Observer, are built directly into JavaScript's event system. Others, like the Singleton, require more careful thinking in a language without class-level access control. The patterns remain relevant, but their implementations look different in modern JavaScript than in the original C++ examples.

GANG OF FOUR — QUICK FACTS
-----------------------------------------------------------
Authors     Erich Gamma, Richard Helm,
            Ralph Johnson, John Vlissides
Published   1994 (Addison-Wesley)
Language    C++ and Smalltalk (original examples)
Patterns    23 total
Categories  3: Creational, Structural, Behavioral
-----------------------------------------------------------

[INTERNAL-LINK: how abstraction and interfaces connect to pattern design → Lesson 3.3: Interface]


What Are the Three Pattern Categories?

The 23 GoF patterns are divided into three categories based on the kind of problem they solve. Understanding the category tells you immediately what aspect of your system the pattern is designed to improve.

Creational Patterns — How Objects Are Made

Creational patterns deal with object creation. They abstract the instantiation process so that your code does not depend on knowing the exact class of object being created. This matters when the type of object to create is determined at runtime, when creation logic is complex enough to deserve its own home, or when you need to control the number of instances in existence.

The central problem creational patterns solve: if your code is full of new ConcreteClass() calls, every change to that class name or constructor signature ripples across every call site. Creational patterns centralize that decision.

Patterns in this category: Singleton, Factory Method, Abstract Factory, Builder, Prototype.

This chapter covers: Singleton (Lesson 8.2), Factory (Lesson 8.3), Builder (Lesson 8.4).

Structural Patterns — How Objects Are Composed

Structural patterns deal with how classes and objects are assembled into larger structures. They answer the question: how do you compose objects so that the structure is flexible and efficient, without creating rigid dependencies between parts?

The central problem structural patterns solve: two systems or classes need to work together, but their interfaces don't match, or you need to add behavior without modifying the original class, or you need to simplify a complex subsystem behind a clean interface.

Patterns in this category: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.

This chapter does not cover structural patterns in depth; they are covered in the advanced design patterns course.

Behavioral Patterns — How Objects Communicate

Behavioral patterns deal with algorithms and the assignment of responsibility between objects. They answer the question: how do objects talk to each other? How do you distribute logic across objects without hardcoding dependencies between them?

The central problem behavioral patterns solve: as systems grow, a single class accumulates too much logic for handling variations in behavior. Behavioral patterns move that variation into separate, interchangeable objects.

Patterns in this category: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor.

This chapter covers: Strategy (Lesson 8.5), State (Lesson 8.6).

[IMAGE: Three-column diagram — left column "Creational" in neon green with object creation icons, center column "Structural" in neon orange with interlocking block icons, right column "Behavioral" in white with communication arrow icons. Each column lists 2-3 pattern names below the header. Dark background - search terms: "design pattern categories creational structural behavioral diagram"]


How Is a Pattern Structured? The Four Parts

Every GoF pattern is described using the same four-part structure. Knowing this structure is useful for two reasons: it helps you read pattern documentation more efficiently, and it gives you a precise framework for explaining a pattern in an interview.

Name

The pattern's name is its vocabulary entry. A good pattern name is specific enough to be unambiguous (everyone means the same thing by "Singleton") and short enough to use in conversation. The name carries the intent — if you hear "Builder," you immediately know the problem involves complex object construction. If you hear "Observer," you know it involves event notification.

Problem

The problem section describes the context: when does this pattern apply? What is the situation you're in before the pattern is needed? This is the trigger. A well-stated problem is specific: not "when object creation is hard" but "when the type of object to create should be determined by a subclass at runtime, not the calling code."

Interviewers often probe this part. "You said you used Factory — what was the specific problem?" If you can't answer that clearly, it signals you applied the pattern by label rather than by judgment.

Solution

The solution describes the classes, their relationships, responsibilities, and how they collaborate. This is the structural diagram in a GoF pattern. It does not give you the code for your specific problem — it gives you the arrangement of participants that solves the problem class.

The solution is also where you see the abstraction layer the pattern introduces. Almost every pattern inserts an interface or abstract class between the caller and the concrete implementation. That indirection is the mechanism that makes the pattern work.

Consequences

The consequences section is the trade-off register. Every pattern has costs: more classes, more indirection, harder initial reading for someone unfamiliar with the pattern, potential performance overhead. Interviewers who ask about trade-offs are specifically probing whether you read only the "solution" section or whether you understood the full consequences.

PATTERN STRUCTURE — FOUR PARTS
-----------------------------------------------------------
Part            What It Contains
-----------------------------------------------------------
Name            Vocabulary: precise label used in discussion

Problem         Context: the specific situation where this
                pattern applies. Includes pre-conditions and
                forces driving the design decision.

Solution        Structure: the classes, interfaces, and
                relationships that solve the problem.
                Not a concrete implementation — a template.

Consequences    Trade-offs: what you gain (flexibility,
                extensibility, decoupling) and what you
                pay (more classes, more indirection,
                complexity for simple cases).
-----------------------------------------------------------

[INTERNAL-LINK: how SOLID principles connect to pattern design decisions → Lesson 7.2: Open/Closed Principle]


Code Example — Pattern Structure in Practice

This example shows the four parts of a pattern applied to a concrete situation. The pattern itself (Factory Method) is covered in full in Lesson 8.3. Here the goal is to see the four-part structure in action, not to master Factory.

// -----------------------------------------------------------------
// PROBLEM: A notification system needs to create different
// notification objects (Email, SMS, Push) based on a string key.
// The calling code should not need to know the concrete class names.
// Adding a new notification type should not require changing the
// calling code — only the creation logic.
// -----------------------------------------------------------------

// SOLUTION: Centralize creation in a factory function.
// The caller depends on the abstract Notification interface,
// not on any concrete class.

// Abstract base — defines the contract all notifications must follow
class Notification {
  constructor(recipient, message) {
    this.recipient = recipient;
    this.message = message;
  }

  // Every concrete notification must implement send()
  send() {
    throw new Error(`${this.constructor.name} must implement send()`);
  }

  describe() {
    return `${this.constructor.name} to ${this.recipient}`;
  }
}

// Concrete implementations — each satisfies the Notification contract
class EmailNotification extends Notification {
  send() {
    console.log(`Email sent to ${this.recipient}: ${this.message}`);
  }
}

class SMSNotification extends Notification {
  send() {
    console.log(`SMS to ${this.recipient}: ${this.message}`);
  }
}

class PushNotification extends Notification {
  send() {
    console.log(`Push to ${this.recipient}: ${this.message}`);
  }
}

// SOLUTION: The factory — centralizes the creation decision
// Calling code never uses `new EmailNotification` directly
class NotificationFactory {
  static create(type, recipient, message) {
    // Registry maps string keys to constructors
    // Adding a new type means adding one entry here — nothing else changes
    const registry = {
      email: EmailNotification,
      sms: SMSNotification,
      push: PushNotification,
    };

    const Constructor = registry[type.toLowerCase()];

    if (!Constructor) {
      throw new Error(`Unknown notification type: ${type}`);
    }

    return new Constructor(recipient, message);
  }
}

// -----------------------------------------------------------------
// CALLING CODE — depends only on the factory and the base contract
// No concrete class names appear here
// -----------------------------------------------------------------
const notifications = [
  NotificationFactory.create("email", "alice@example.com", "Your order shipped."),
  NotificationFactory.create("sms",   "+1-555-0100",       "Your code: 847291"),
  NotificationFactory.create("push",  "device-xyz",        "New message from Dave"),
];

// Polymorphic dispatch — each object's send() runs at runtime
notifications.forEach((n) => {
  console.log(n.describe());
  n.send();
});

// Output:
// EmailNotification to alice@example.com
// Email sent to alice@example.com: Your order shipped.
//
// SMSNotification to +1-555-0100
// SMS to +1-555-0100: Your code: 847291
//
// PushNotification to device-xyz
// Push to device-xyz: New message from Dave

// -----------------------------------------------------------------
// CONSEQUENCES (trade-offs of this pattern):
//
// Gain: adding "slack" or "webhook" type requires one new class
//       and one new registry entry — zero changes to calling code
//
// Gain: calling code is decoupled from concrete class names,
//       making it easier to test with mock implementations
//
// Cost: more files and classes than a simple switch-statement
//       would require for a system with only 3 notification types
//
// Cost: the registry pattern (string -> constructor) is implicit;
//       a developer new to the codebase must find the factory file
//       to understand what types are available
// -----------------------------------------------------------------

What Are Design Patterns? visual 1


What Patterns Does This Chapter Cover?

This chapter covers six patterns selected because they appear most frequently in interviews for mid-level and senior roles. Three are creational, two are behavioral, and one structural pattern (covered in context) threads through the others.

The selection criteria: each pattern solves a problem that comes up in real application code (not academic exercises), each one has a clear interview question attached to it, and together they demonstrate all three categories.

CHAPTER 8 — PATTERNS COVERED
-----------------------------------------------------------
Lesson   Pattern     Category      Core Problem Solved
-----------------------------------------------------------
8.1      Overview    All three     What patterns are and why
                                   they exist (this lesson)

8.2      Singleton   Creational    Ensure exactly one instance
                                   of a class exists globally

8.3      Factory     Creational    Decouple object creation
                                   from the calling code

8.4      Builder     Creational    Construct complex objects
                                   step by step, with optional
                                   parameters cleanly handled

8.5      Strategy    Behavioral    Replace if/else chains with
                                   interchangeable algorithm
                                   objects

8.6      State       Behavioral    Change object behavior
                                   based on internal state
                                   without large conditionals
-----------------------------------------------------------

[INTERNAL-LINK: how composition supports pattern design → Lesson 4.6: Composition vs Inheritance]


Common Mistakes

  • Treating patterns as mandatory architecture. A pattern is a solution to a specific problem. If you don't have that problem, the pattern adds complexity with no benefit. The most common misapplication is using Singleton everywhere because it is the first pattern most developers learn. Patterns are tools for specific problems, not default structure.

  • Memorizing the pattern name without knowing the problem it solves. Interviewers follow up every pattern name with "what problem does that solve?" or "when would you not use it?" Knowing the name without the problem and the trade-offs fails that follow-up. Study each pattern's problem statement as carefully as its solution.

  • Confusing categories. Creational, Structural, and Behavioral are not the same thing. Mixing them up in an interview signals superficial familiarity. A reliable heuristic: Creational = about making objects. Structural = about assembling objects. Behavioral = about objects talking to each other and sharing responsibility.

  • Applying patterns to simple problems. A three-class system does not need a Factory. A single algorithm does not need a Strategy. Over-engineering with patterns is a recognized anti-pattern in itself. Part of demonstrating mastery is knowing when NOT to apply a pattern.

  • Describing a pattern without describing the context. In interviews, always lead with the problem, not the pattern name. "I needed a way to create different report objects without the controller knowing the concrete type" is a stronger opening than "I used the Factory pattern." The problem statement proves you chose the pattern deliberately, not by habit.


Interview Questions

Q: What is a design pattern and why would you use one instead of writing custom code?

A design pattern is a named, reusable solution to a recurring problem in object-oriented design. It is not code you copy — it is a structural template you adapt to your specific context. You use one because it captures a proven solution to a known problem, gives your team a shared vocabulary for the decision, and makes your intent visible to any developer who recognizes the pattern. The alternative is solving the same structural problem from scratch every time, producing slightly different (and undiscussed) solutions across a codebase.

Q: What are the three GoF pattern categories? Give one example from each.

The three categories are Creational, Structural, and Behavioral. Creational patterns control object creation — Singleton ensures only one instance of a class exists. Structural patterns deal with object composition — Adapter makes two incompatible interfaces work together. Behavioral patterns manage how objects communicate and distribute responsibility — Strategy replaces conditional logic by making algorithms interchangeable objects. The category tells you immediately what aspect of your system the pattern is designed to improve.

Q: What are the four parts of a GoF pattern description?

Every GoF pattern is described in four parts. The name is the vocabulary entry used in team discussion. The problem describes the specific context and conditions under which the pattern applies. The solution describes the classes, interfaces, and their relationships — it is a structural template, not a code sample. The consequences list the trade-offs: what flexibility or extensibility you gain, and what costs you pay in complexity, indirection, or class count. Interviewers probe the consequences section specifically to test whether you understand the full cost of a pattern, not just its mechanics.

Q: How do you decide which pattern to use in a given situation?

Start with the problem, not the pattern. Identify the recurring structural problem you are facing: is it about controlling how objects are created? About connecting incompatible interfaces? About varying behavior at runtime without conditionals? The answer points to a category. Within that category, match the specific forces in your problem to the specific problem statement of each pattern. If no pattern fits cleanly, write straightforward code first. A pattern applied to the wrong problem is worse than no pattern at all, because it adds complexity that misleads the next developer.

Q: Why do design patterns sometimes get criticized? What are the valid objections?

The valid objections fall into three groups. First, patterns can encourage over-engineering: developers reach for a Singleton or a Factory on a two-class problem that would be clearer with a simple function. Second, some patterns were designed for statically typed languages like Java and C++ and become unnecessary in dynamic languages like JavaScript, where the language handles the flexibility natively (the Observer pattern, for example, is essentially the DOM event system). Third, patterns can become a vocabulary substitute for actual understanding — a developer who names every pattern in their codebase but can't articulate the specific problem each one was solving is demonstrating pattern recognition, not engineering judgment.


Quick Reference Cheat Sheet

DESIGN PATTERNS — CHAPTER 8 REFERENCE
-----------------------------------------------------------
WHAT IS A DESIGN PATTERN?
  A named, reusable solution to a recurring OOP design
  problem. Not copy-paste code — a structural template
  adapted to your specific context.

WHO: Gang of Four (Gamma, Helm, Johnson, Vlissides)
WHEN: Published 1994 in "Design Patterns: Elements of
      Reusable Object-Oriented Software"
COUNT: 23 patterns across 3 categories

-----------------------------------------------------------
THREE CATEGORIES
-----------------------------------------------------------
Creational       Structural       Behavioral
-----------      -----------      -----------
How objects      How objects      How objects
are created      are assembled    communicate

Examples:        Examples:        Examples:
- Singleton      - Adapter        - Strategy
- Factory        - Facade         - Observer
- Builder        - Decorator      - State
- Prototype      - Composite      - Command

Core question:   Core question:   Core question:
"Who creates     "How do parts    "Who decides what
this object?"    fit together?"   runs and when?"

-----------------------------------------------------------
FOUR PARTS OF ANY PATTERN
-----------------------------------------------------------
Name           Vocabulary — used in team discussion
Problem        Context — when this pattern applies
Solution       Structure — classes, interfaces, relations
Consequences   Trade-offs — what you gain and what you pay

-----------------------------------------------------------
SIX PATTERNS IN THIS CHAPTER
-----------------------------------------------------------
Singleton      One global instance (config, logger, DB)
Factory        Decouple creation from calling code
Builder        Step-by-step construction, optional params
Strategy       Interchangeable algorithms, remove if/else
State          Behavior changes with internal state

-----------------------------------------------------------
PATTERN SELECTION HEURISTIC
-----------------------------------------------------------
Object creation varies at runtime?     -> Creational
Two interfaces don't fit together?     -> Structural
Behavior varies without new classes?   -> Behavioral

Not sure? Write plain code first.
Add a pattern only when the trade-off is clearly worth it.

-----------------------------------------------------------
COMMON INTERVIEW TRAPS
-----------------------------------------------------------
Trap: naming a pattern without stating the problem it solves
Fix:  always lead with the problem, then name the pattern

Trap: treating patterns as always better than custom code
Fix:  patterns add indirection — justify the cost each time

Trap: confusing categories (Singleton is Creational, not
      Structural; Strategy is Behavioral, not Creational)
Fix:  memorize one clear example per category
-----------------------------------------------------------

What Are Design Patterns? visual 2


[PERSONAL EXPERIENCE]: The most effective way to prepare design patterns for interviews is not to read all 23 patterns and try to memorize them. Study five or six deeply enough that you can state the problem, sketch the class structure, write a small working example, and explain two trade-offs for each. Shallow familiarity with 23 patterns produces worse interview answers than deep familiarity with six. Interviewers probe, and shallow knowledge collapses under one follow-up question.


Previous: Lesson 7.5 - Dependency Inversion Principle Next: Lesson 8.2 - Singleton Pattern


This is Lesson 8.1 of the OOP Interview Prep Course — 8 chapters, 41 lessons.

On this page