2.2.11 · D1Design Principles

Foundations — Design Patterns — Structural - Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

2,133 words10 min readBack to topic

Before you can read a single line of the parent note, you need a handful of ideas that it assumes you already carry. This page builds each one from absolute zero: plain words → a picture → why the topic can't move without it. Nothing here is advanced; a smart 12-year-old who has never written code can follow from line one.


0. What even is an "object"?

Figure — Design Patterns — Structural -  Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

The picture: a rounded box. Top half = data slots (labelled kb = 12). Bottom half = a button labelled size(). You press the button by writing object.size().

Why the topic needs it: Every pattern in the parent note is a diagram of boxes. If "object" is fuzzy, the whole page is fuzzy.


The picture: one cutter on the left, three identical cookies on the right, an arrow labelled "stamp / instantiate" between them.

Why the topic needs it: Patterns like Flyweight turn on the difference between "how many blueprints" (26 glyph classes) versus "how many cookies" (a million characters). Mix these up and Flyweight makes no sense.

Recall Class or object:

Circle in class Circle: ? Class — it's the blueprint, not a stamped-out thing.


2. Interface — the shape of the buttons

Figure — Design Patterns — Structural -  Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

The picture: two very different machines (a shiny one, a rusty one) with the same three buttons on their front panels. A hand can operate either one without looking inside — because the buttons match.

Why the topic needs it: This single idea powers half the patterns:

  • Adapter exists because two objects have different button layouts and must be made to match.
  • Decorator works because the wrapper keeps the same interface — so you can stack wrappers and nobody notices.
  • Composite works because leaf and group share one interface (size()), so the client presses the same button on both.

3. Composition — a box holding another box

Figure — Design Patterns — Structural -  Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

The picture: a big box labelled Milk with a small box Coffee nested inside it, connected by an arrow labelled self.drink. The outer box has a cost() button; when pressed, an arrow forwards the press down to the inner box's cost() button, then adds a little +0.5.

Why the topic needs it — this is THE 80%: The parent note says "Almost every structural pattern is just one object holding a reference to another object and forwarding calls to it." That sentence is composition. See Composition over Inheritance for the deeper argument that this is usually better than the alternative below.


4. Forwarding — the arrow that does the work

Why the topic needs it: The parent note distinguishes the seven patterns purely by what you do around the forward:

Pattern What happens around the forward
Adapter rename the button (translate playstart_mp4)
Decorator forward, then add a bit (+0.5)
Proxy forward only if allowed (permission / cache / lazy)
Facade forward to many inner objects in order
Composite forward to a collection of inner objects

Keep "forward, differing by intent" in your head and the whole parent page collapses into one sentence.


5. Combinations and the "class explosion"

Figure — Design Patterns — Structural -  Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

The picture: left panel — a full grid of 12 tiny class-boxes ("one per combination", drawn in red). Right panel — two short separate stacks of 3 and 4 boxes joined by a single arrow ("has-a", drawn in green), total 7. The visual gap is the argument for Bridge and Decorator.

Why the topic needs it: The parent's Bridge section ("class explosion, vs ") and its Decorator "steel-man" ("you'd need a class for every combination") are both this one idea.


6. Recursion — a rule that calls itself

The picture (in your head): a folder opens into sub-folders which open into sub-folders which finally open into files. The same size() question echoes down the tree and the answers add up on the way back. Deep dive in Recursion.

Why the topic needs it: Composite is recursion made into a pattern. Folder.size() calls size() on each child without checking its type — the recursion is the pattern.

Recall What stops recursion from going forever?

The base case — a piece small enough to answer directly. For files, size() just returns self.kb; it does not recurse.


7. Intrinsic vs extrinsic — shared part vs per-thing part

The picture: one bold glyph 'a' in the centre (shared, drawn once), with three faint arrows pointing to three positions on a page, each tagged with its own (x, y) — the same shape, three different placements.

Why the topic needs it: This single split is Flyweight. Store the intrinsic part once, pass the extrinsic part each time — 26 glyph objects instead of a million.


Prerequisite map

Object = data plus methods

Interface = button layout

Class vs Object

Composition: box holds box

Forwarding: pass the call along

Structural Patterns

Class explosion m times n

Recursion: rule calls itself

Intrinsic vs Extrinsic state

Each foundation feeds the topic: composition + forwarding give you Adapter, Decorator, Proxy, Facade, Bridge; recursion gives you Composite; class-explosion motivates Bridge and Decorator; intrinsic/extrinsic gives you Flyweight.


  • Open-Closed Principle — patterns let you add features without editing old code (decorate, don't rewrite).
  • Single Responsibility Principle — each wrapper does one job, which is why they stack cleanly.
  • Dependency Inversion — depend on the interface (button layout), not the concrete class, so any wrapper fits.
  • Creational Patterns and Behavioral Patterns — the other two families of the same catalogue.

Equipment checklist

Cover the right side and answer out loud. If any line stumps you, re-read its section above before opening the parent note.

I can state, in one sentence, what an object is
A memory box holding data (facts it remembers) plus methods (actions it can do).
I can explain the dot in a.b(x)
Press method b on object a, handing it input x.
I know the difference between a class and an object
Class is the cookie-cutter (blueprint); object is one stamped-out cookie.
I can define an interface without mentioning behaviour
The list of button names and their inputs an object promises — not what happens inside.
I can say why "same interface" lets Decorators stack
Each wrapper looks identical from outside, so wraps nest and nobody below notices.
I can describe composition in one phrase
One object has-a reference to another and uses it (self.inner = inner).
I can contrast has-a with is-a
Composition (has-a) is chosen at run time and flexible; inheritance (is-a) is fixed at write time.
I can explain forwarding
A method passes the call along to the inner object instead of doing the work itself.
I can compute the class-explosion numbers for 3 shapes × 4 colours
12 classes by inheritance versus 7 by composition (3+4).
I can name the base case idea in recursion
A piece small enough to answer directly, stopping the self-calls (a File just returns its kb).
I can split a letter-on-a-page into intrinsic and extrinsic
Intrinsic = shared glyph shape; extrinsic = per-copy position and colour.