Foundations · Guide · Start here

Foundations: Patterns & the Go Mindset

What design patterns are, why they exist, and why they look so different in Go than in Java or C++.

Foundations Start here Complete

In one line. A design pattern is a named, proven solution to a problem that keeps coming up — a shared vocabulary that lets one engineer say “let’s use a Strategy here” and another instantly know what they mean.

Patterns aren’t code you download. They’re descriptions of a design that you adapt to your language and problem. The catalog comes from the 1994 book Design Patterns by the “Gang of Four” (GoF), which cataloged 23 of them. That catalog is the backbone of this guide — but we read it through a Go lens, because Go changes the answers.

Why patterns are worth your time

🗣️

Shared vocabulary

"Wrap it in a Decorator" compresses a paragraph of explanation into two words on a code review.

🧩

Tried-and-tested

Each pattern encodes trade-offs people already learned the hard way, so you skip some of the mistakes.

🔌

Design for change

Most patterns exist to isolate the part of a system most likely to change behind a stable interface.

The three families

The 23 GoF patterns split into three groups by what kind of problem they solve.

graph TD
  A["Design Patterns (GoF)"] --> C["Creational<br/>how objects are made"]
  A --> S["Structural<br/>how objects are composed"]
  A --> B["Behavioral<br/>how objects interact"]
  C --> C1["Singleton · Factory Method<br/>Abstract Factory · Builder · Prototype"]
  S --> S1["Adapter · Bridge · Composite · Decorator<br/>Facade · Flyweight · Proxy"]
  B --> B1["Strategy · Observer · Command · State<br/>Iterator · Template Method · and more"]

🎯 A quick way to remember them

Creational = the birth of objects. Structural = the shape objects form together. Behavioral = the conversation between objects.

Why Go is different

Most pattern tutorials are written for Java or C++. Go deliberately omits features those languages lean on — and that changes everything.

Java / C++ relies on… Go gives you instead… Effect on patterns
Class inheritance Struct embedding (composition) Template Method, Decorator become composition
Explicit implements Implicit, small interfaces Adapter & Strategy get trivial
Objects everywhere First-class functions Strategy/Command can be a func value
Threads + locks Goroutines + channels Observer/Pub-Sub become channel-native
Constructors Plain NewX() functions Factory Method is just a function

🐹 The Go proverbs that matter here

Accept interfaces, return structs.” · “The bigger the interface, the weaker the abstraction.” · “Don’t communicate by sharing memory; share memory by communicating.” Each one quietly rewrites a classic pattern.

So in this guide, every pattern page asks two questions: what’s the classic shape? and what does it actually look like in idiomatic Go? Sometimes the answer is “a one-line function.” That’s a feature, not a disappointment.

The four pillars behind Go’s approach

  • Interfaces are implicit. A type satisfies an interface just by having the methods — no implements keyword. This makes Adapter, Strategy and Dependency Injection nearly free.
  • Embedding, not inheritance. Put a struct inside another and its methods are promoted. You get reuse without a class hierarchy.
  • Functions are values. You can pass behavior directly, so many “make an object to hold one method” patterns collapse.
  • Concurrency is built in. Goroutines and channels turn Observer, Pipeline and Pub/Sub into language-level idioms.

How to read a pattern page

Every pattern in this guide follows the same structure, so you always know where to look:

Intent & analogy

One-line purpose plus a real-world story to anchor it in memory.

Problem & structure

The pain it removes, then a UML diagram of the moving parts.

Idiomatic Go

Runnable Go code — the Go-native form, not a Java translation.

Trade-offs & quiz

When to use it, when not to, where the stdlib uses it, and a self-check.

✅ Mark pages as 'learned'

Use the Mark as learned button on every pattern page to track your journey. Your progress bars on the home page fill up as you go — it’s all saved in your browser.

Ready? The most natural place to begin is the very first creational pattern.

Check your understanding

Score: 0 / 3

1. What is a design pattern, most precisely?

A pattern is a description of a solution — a shared vocabulary — not code you import. You implement it yourself, shaped by your language.

2. Why do several classic patterns shrink or vanish in Go?

Many GoF patterns work around the absence of features Go has built in. Strategy is often just a function value; Iterator is range; Observer leans on channels.

3. Which statement reflects idiomatic Go best?

Go has no inheritance. It composes behavior with struct embedding and satisfies small, implicit interfaces — accept interfaces, return structs.