Practice · Guide · Reference

Patterns Cheat-Sheet

A one-page map of every pattern — its intent, the idiomatic Go form, and when to reach for it. Built for revision and interview prep.

Practice Reference Complete

The whole catalog at a glance. Each row links to the full page; skim to find the right tool, then dive in.

🎯 How to read this

Intent is the one-line purpose. Idiomatic Go is the form you’ll actually write — often lighter than the textbook version, because Go’s interfaces, functions, embedding, and goroutines do a lot of the work.

Creational — how objects get made

Pattern Intent Idiomatic Go
Singleton One instance, one access point sync.Once; a package-level var
Factory Method Decide which concrete type to build, behind an interface NewX() Iface; a creation method per context
Abstract Factory Create a family of related objects that must match A factory interface with several Create… methods
Builder Construct a complex object step by step Functional options: New(req, ...Option)
Prototype Create new objects by cloning a configured one Explicit Clone(); slices.Clone / maps.Clone

Structural — how objects compose

Pattern Intent Idiomatic Go
Adapter Make an incompatible type fit an expected interface A wrapper with the target’s methods (http.HandlerFunc)
Bridge Separate an abstraction from its implementation Hold the implementation as an interface field
Composite Treat leaves and trees uniformly An interface + a node holding []Iface
Decorator Add behavior by wrapping, same interface Embed the interface; io wrappers, middleware
Facade One simple entry over a complex subsystem A struct holding subsystems, coarse methods
Flyweight Share immutable state across many objects A cache/interning factory of shared values
Proxy A stand-in that controls access Same interface, wraps the subject (lazy, cache, ReverseProxy)

Behavioral — how objects collaborate

Pattern Intent Idiomatic Go
Chain of Responsibility Pass a request along handlers until one handles it HTTP middleware func(next) Handler
Command Capture a request as an object (queue, log, undo) Execute/Undo interface; or a func()
Interpreter Evaluate sentences of a small grammar Tree of Eval() nodes (Composite + recursion)
Iterator Traverse a collection without exposing it range, channels, or iter.Seq (Go 1.23)
Mediator Centralize many-to-many communication A hub struct colleagues talk to
Memento Snapshot/restore state without breaking encapsulation Opaque struct with unexported fields
Observer Notify many dependents on change An interface list, or channels + goroutines
State Change behavior with internal state One type per state implementing a State interface
Strategy Swap interchangeable algorithms at runtime A func value or small interface (sort.Slice)
Template Method Fixed skeleton, caller fills the steps Inject steps as an interface or func fields
Visitor Add operations to a stable set of types Accept/Visit double dispatch, or a type switch

Concurrency — the Go specials

Pattern Intent Idiomatic Go
Generator Lazy/infinite stream from a goroutine func(done) <-chan T; producer closes the channel
Pipeline Stream through channel-connected stages Each stage owns and closes its output channel
Fan-out / Fan-in Parallelize a stage, then merge results N workers on one chan; WaitGroup to merge & close
Worker Pool Bound concurrency with N workers A jobs channel + a fixed set of workers
Semaphore Cap how many run at once Buffered chan struct{}; x/sync/semaphore
Context & Cancellation Propagate cancel, deadline, request values ctx first arg; select on ctx.Done()
Or-done Range a stream that stops cleanly on cancel Wrap each receive in a select on done
errgroup Concurrent tasks: wait + first error + cancel errgroup.WithContext, g.Go, g.SetLimit
Pub/Sub Broadcast to dynamic subscribers A broker: mutex-guarded map of channels

Decision shortcuts — “I need to…”

✅ Pick a pattern by what you're trying to do

Patterns Go quietly reshapes

🐹 Where a 'pattern' becomes a one-liner

  • Strategy → a func value (sort.Slice’s less)
  • Iteratorrange and iter.Seq
  • Singletonsync.Once
  • Observer / Pub-Sub → channels + goroutines
  • Decorator / Chain of Responsibilityio wrappers and HTTP middleware
  • Template Method / Bridge → struct embedding + an interface field
  • Factory → a plain NewX() function

The lesson from Foundations: in Go, many patterns aren’t ceremonies you build — they’re the natural shape the language already nudges you toward.

Test yourself

Check your understanding

Score: 0 / 4

1. Wrapping an http.Handler to add logging, then auth, then gzip — each keeping the same interface — is which pattern?

Same interface in, same interface out, behavior added by wrapping — Decorator. In HTTP form it's a middleware chain (Chain of Responsibility too).

2. You launch a goroutine per request but want at most 5 hitting the API at once. Which pattern?

A counting semaphore caps how many goroutines are in the critical section while you still spawn one per task. A worker pool is the alternative when you have a fixed queue.

3. Letting callers decide how a slice is sorted by passing a comparison function is…

An interchangeable algorithm chosen at runtime — Strategy. In Go it's just a func value, exactly like sort.Slice's `less`.

4. You need exactly one shared config, initialized once, safe under concurrency.

One instance, one access point, initialized once — Singleton, and sync.Once makes the lazy version race-free.