Understanding Design Patterns — Syllabus

Generated by Lugh | Source: Gang of Four (GoF), refactoring.guru Depth: 2 (Functional Literacy)

What this course covers

The 22 classic GoF design patterns — what problem each one solves, when to reach for it, and when it’s overkill. Examples grounded in Ruby and Rails where possible, since that’s the world you live in.

What this course does NOT cover

This won’t make you a pattern architect. You won’t be able to design new patterns or critique the GoF taxonomy itself. You also won’t memorize UML diagrams — if you need one, you’ll look it up. The goal is recognition and judgment: seeing a problem and knowing which pattern fits, or knowing that none do and that’s fine.

Honest expectations

After completing this course, you will be able to:

  • Name and describe all 22 GoF patterns from memory (at least the gist)
  • Recognize patterns you’re already using in Rails without knowing the name
  • Choose between similar patterns (Strategy vs State, Decorator vs Proxy)
  • Explain to a junior dev why a pattern exists, not just how it works
  • Articulate when a pattern is the wrong choice (over-engineering, wrong abstraction level)

You will NOT be able to:

  • Design novel patterns
  • Evaluate patterns from other catalogs (POSA, EIP, etc.)
  • Apply these fluently in languages with very different paradigms (Haskell, Rust) without additional study

Tier 1 — Foundations (Episodes 1-3)

What patterns are, why they exist, and the five you already know from Rails.

Episode 1: What are design patterns, actually?

Learning objectives:

  • Explain what a design pattern is without using the word “pattern”
  • Describe why the Gang of Four book exists and what problem it was solving in 1994
  • Articulate the three categories (Creational, Structural, Behavioral) and what each category is about
  • Identify the difference between a pattern and a recipe

Common misconception to address: “Design patterns are best practices you should always use.” They’re not — they’re tradeoffs with names. Every pattern adds complexity. The name is the value, not the implementation.

Episode 2: Patterns you already use in Rails

Learning objectives:

  • Identify Observer pattern in ActiveRecord callbacks and Action Cable
  • Identify Strategy pattern in Rails routing and callable objects
  • Identify Template Method in ApplicationController and inheritance hooks
  • Identify Iterator in .each, .map, Enumerable
  • Identify Builder pattern in ActiveRecord query interface and form builders
  • Explain why recognizing existing patterns matters more than memorizing new ones

Why this episode exists: Most working developers use patterns daily without naming them. Attaching names to things you already do is the fastest path to the vocabulary.

Episode 3: The creational patterns

Learning objectives:

  • Explain the problem all creational patterns share: “how do I make objects without hardcoding the exact class?”
  • Describe Factory Method, Abstract Factory, Builder, Prototype, and Singleton
  • Explain why Singleton is controversial and when it’s genuinely appropriate
  • Identify which creational patterns appear in Ruby’s standard library and Rails

Patterns covered: Factory Method, Abstract Factory, Builder, Prototype, Singleton


Tier 2 — The structural patterns (Episodes 4-6)

How objects compose into larger structures.

Episode 4: Wrapper patterns — Adapter, Decorator, Proxy

Learning objectives:

  • Explain what all three have in common (they wrap another object) and how they differ in intent
  • Adapter: making incompatible interfaces work together (API client wrappers, legacy system integration)
  • Decorator: adding behavior without subclassing (Draper gem, middleware stacks)
  • Proxy: controlling access to an object (lazy loading, access control, caching)
  • Given a scenario, choose the right wrapper pattern and explain why

Common misconception to address: These three get confused constantly because they look structurally similar. The difference is why you’re wrapping, not how.

Episode 5: Composition patterns — Composite, Bridge, Facade, Flyweight

Learning objectives:

  • Composite: treating individual objects and groups uniformly (file systems, UI component trees, nested comments)
  • Facade: simplifying a complex subsystem behind a clean interface (Rails has_many :through, service objects)
  • Bridge: separating abstraction from implementation (cross-platform rendering, database adapters)
  • Flyweight: sharing state to save memory (string interning, connection pools)
  • Explain which of these four you’d reach for most often in a Rails API context

Honest note: Bridge and Flyweight are the least commonly needed in typical Rails work. The episode covers them for completeness but is honest about frequency of use.

Episode 6: Structural patterns in practice

Learning objectives:

  • Given 3-4 real-world Rails scenarios, identify which structural pattern applies
  • Explain how Rack middleware is a Decorator chain
  • Explain how ActiveRecord associations use Proxy
  • Articulate when “just use a plain object” is better than any structural pattern

Tier 3 — The behavioral patterns (Episodes 7-10)

How objects communicate and divide responsibility.

Episode 7: Communication patterns — Observer, Mediator, Chain of Responsibility

Learning objectives:

  • Observer: one-to-many notification (pub/sub, webhooks, ActiveSupport::Notifications)
  • Mediator: centralizing complex communication (chat rooms, form validation coordinators, Sidekiq)
  • Chain of Responsibility: passing requests along a chain until one handles it (Rack middleware, exception handling, authorization layers)
  • Explain the tradeoff between Observer (decoupled but hard to debug) and Mediator (centralized but a potential god object)

Episode 8: Strategy, State, and Template Method

Learning objectives:

  • Strategy: swapping algorithms at runtime (pricing calculators, serialization formats, authentication providers)
  • State: changing behavior based on internal state (order status machines, connection states, AASM gem)
  • Template Method: defining a skeleton with overridable steps (ApplicationController, Rails generators)
  • Distinguish Strategy from State — same structure, different intent
  • Identify when a simple case statement is better than either pattern

Common misconception to address: “Strategy and State are the same thing.” They use the same mechanism (delegation to interchangeable objects) but answer different questions. Strategy asks “which algorithm?” State asks “what mode am I in?”

Episode 9: Command, Memento, Iterator, Visitor

Learning objectives:

  • Command: encapsulating a request as an object (job queues, undo/redo, Sidekiq workers)
  • Memento: capturing and restoring state (draft saving, undo, PaperTrail gem)
  • Iterator: traversing a collection without exposing internals (Enumerable, custom collection objects)
  • Visitor: adding operations to objects without modifying them (AST walkers, report generators, Arel)
  • Explain why Visitor is powerful but rarely worth the complexity in Ruby

Episode 10: Patterns, anti-patterns, and judgment

Learning objectives:

  • Identify common over-engineering mistakes (pattern for pattern’s sake)
  • Explain the “if you have a hammer” problem with patterns
  • Describe when not to use a pattern (YAGNI, premature abstraction)
  • Articulate patterns that Ruby makes unnecessary (many GoF patterns exist because Java/C++ lack features Ruby has built in — blocks, mixins, duck typing)
  • Given a messy codebase scenario, identify which pattern would help and which would make it worse

Why this episode matters: The most valuable skill isn’t knowing patterns — it’s knowing when the pattern costs more than the problem.


Source materials

  • Gang of Four: Design Patterns: Elements of Reusable Object-Oriented Software (1994)
  • refactoring.guru/design-patterns — visual explanations with Ruby code examples
  • Ruby/Rails ecosystem examples drawn from: Draper, AASM, PaperTrail, Rack, ActiveSupport, Sidekiq

Prerequisites

  • Comfortable reading Ruby code
  • Basic OOP concepts (classes, inheritance, interfaces/duck typing)
  • Some Rails experience (for the examples to land, not for the concepts)