Originally published on phpdesignpatterns.dev — part of the PHP design patterns course. View this lesson on the original site.

Structural patterns in plain English

Structural patterns are about how objects fit together. Where creational patterns shape construction, structural patterns shape composition: how a class wraps another class, how an interface insulates a caller from a subsystem, how a tree of small objects pretends to be a single large one. They're the patterns you reach for when the wiring between objects is what's hurting, not the objects themselves.

Structural design patterns map

The pressure they relieve

You'll feel the need for a structural pattern when:

  • A class you depend on has the wrong shape — wrong method names, wrong return types, wrong abstraction level — and you can't (or shouldn't) change it.
  • A subsystem has too many moving parts for callers to understand, and you want to give them one well-named entry point.
  • You want to add behaviour to an object without modifying it — logging, caching, retries — and without touching every caller.
  • A small object and a tree of small objects need to be treated the same way by client code.
  • The number of variations is multiplying — N kinds of message × M kinds of channel — and you don't want N × M concrete classes.
  • A reference to a real object should be stood in for by a cheaper, lazier, or access-controlled placeholder.

The patterns in this family

This course covers eight structural patterns:

  • Adapter (chapter 5). Translate one interface into another. Use it when you've got a class that does what you need but speaks the wrong protocol — a third-party SDK, a legacy service, an external API.
  • Decorator (chapter 6). Wrap an object in another object that implements the same interface, adding behaviour around the wrapped one. Use it when you want stackable, optional cross-cutting behaviour (logging, caching, rate limiting) without baking it into the core class.
  • Facade (chapter 7). A single class that hides a complex subsystem behind a simple, task-shaped API. Use it when callers only ever do one or two tasks against a sprawling internal world and shouldn't need to learn it.
  • Repository (chapter 8). A collection-shaped abstraction over storage, so domain code talks about finding orders, not about SQL or HTTP. Strictly an application pattern rather than a GoF one, but ubiquitous enough in modern PHP that it's earned its chapter.
  • Composite (chapter 17). Treat a single thing and a tree of things uniformly through one interface. Use it for menus, file systems, organisational charts — anything where leaves and branches answer the same questions.
  • Proxy (chapter 18). A stand-in object that controls access to a real one — for lazy loading, access control, remote calls, or caching. Same interface as the real object; different mechanics.
  • Bridge (chapter 20). Separate an abstraction from its implementation so they can vary independently. Use it when you'd otherwise end up with a RedNotificationToSlack, BlueNotificationToSlack, RedNotificationToEmail, BlueNotificationToEmail… combinatorial explosion.
  • Flyweight (chapter 21). Share a single instance of a value-like object across many places that all need the same data. Use it when memory matters and many "things" share most of their state.

What they have in common

Structural patterns all answer the question "how should this object relate to the next one along?" They sit between the things they connect: an adapter between a caller and a foreign API, a decorator between a caller and a service, a proxy between a caller and a remote object, a facade between a caller and a subsystem. The shared shape is same interface, different mechanics.

When you don't need them

You don't need a structural pattern when:

  • The interface you're wrapping is already the right shape and the caller is fine talking to it directly.
  • There's only one variant of the cross-cutting behaviour and it's a single line.
  • The "subsystem" is two methods on one class.

A Decorator chain three layers deep around a class with one method is a sign you wanted a function. A Facade over a service with three methods isn't a Facade — it's a rename.

The next lesson covers the third and largest family: behavioural patterns, which are about how objects interact — how responsibility, state, and communication flow between them.

From PHP design patterns — Introduction to design patterns