Skip to content

Structural Design Patterns: Master Comparison

Structural design patterns deal with how classes and objects are composed to form larger structures.

Builds on Design Pattern: Adapter (Structural), Design Pattern: Decorator (Structural) and The Surrogate for Controlled Access

Stage 3core6 min read

Structural design patterns are about how classes and objects are put together. They let you connect pieces without making each piece depend on the inner details of the others.

"Structure" covers several different problems. An API does not fit. A class hierarchy keeps multiplying. A tree needs one shared interface. Optional behaviour must be layered on. A subsystem is hard to enter. Access needs control. Millions of objects repeat the same data. Each of the seven patterns below solves one of these problems. You cannot swap one for another.

A few terms used on this page:

  • part-whole hierarchy means a tree where a container and a single item are used the same way, such as folders and files;
  • abstraction and implementation in Bridge are two pattern roles: the idea the caller sees and the low-level mechanism behind it. They do not mean the Java keywords abstract and implements;
  • intrinsic state in Flyweight is shared data stored once; extrinsic state is the data that differs per use, which the caller passes in.

1. Quick Comparison Table

PatternPrimary FocusKey MechanismBest For...
AdapterCompatibilityWrapping an object to provide a different interface.Using third-party legacy code or APIs that do not fit.
BridgeIndependenceDecoupling abstraction from its implementation.Two things that vary independently (e.g., OTP/Promo/Order messages x SMS/Email/WhatsApp channels).
CompositeHierarchyTreating individual objects and collections uniformly.Tree structures like File Systems or UI Widget trees.
DecoratorExtensionAdding responsibilities dynamically without inheritance.Optional features like scrollbars on windows or pizza toppings.
FacadeSimplicityProviding a unified, simple entry point to a complex system.Simplifying interaction with a messy library or microservices.
ProxyControlActing as a placeholder to control access to an object.Caching, logging, or lazy loading expensive resources.
FlyweightMemorySharing common state across many similar objects.Managing millions of small objects (e.g., trees in a game).

2. When to Use vs. When to Avoid

Adapter Pattern

  • When to Use: When you want to use an existing class, but its methods do not match the interface you need.
  • When to Avoid: When you own the source code. It is better to change the original class to match the interface.

Bridge Pattern

  • When to Use: When a class varies in two independent directions and subclassing every pair would explode (e.g., 3 message types x 3 channels = 9 classes, versus 3 + 3 with Bridge).
  • When to Avoid: When only one thing changes. Bridge then adds extra code and complexity for no gain.

Composite Pattern

  • When to Use: When you have a part-whole tree and want clients to treat a container and a single item the same way.
  • When to Avoid: When a leaf and a container behave too differently, so the shared interface is awkward or "leaky" (it exposes methods that do not fit one of them).

Decorator Pattern

  • When to Use: When you need to add behavior to one object at runtime without affecting other objects of the same class.
  • When to Avoid: When you would have a long chain of decorators. It becomes very hard to debug and to tell which layer caused an error.

Facade Pattern

  • When to Use: When you want a simple interface to a complex subsystem, or want to split your system into layers.
  • When to Avoid: When clients need full access to the subsystem's features. The facade can become a "God Object" (one class that does too much) if it tries to cover everything.

Proxy Pattern

  • When to Use: When you need more than a plain reference to an object, such as one that caches, delays creation, or checks permissions (e.g., Caching Proxy, Virtual Proxy, Protection Proxy).
  • When to Avoid: When the resource is light and used often. The extra layer (indirection) adds delay for no gain.

Flyweight Pattern

  • When to Use: When a program uses a huge number of objects and most of their data can be made "intrinsic" (shared).
  • When to Avoid: When memory is not a problem, or objects share almost no data. Splitting intrinsic from extrinsic state then adds extra logic for no gain.

3. The "Rule of Thumb" for Decision Making

  1. Are the interfaces incompatible? → Adapter.
  2. Do you have a "Class Explosion" due to two independent dimensions? → Bridge.
  3. Do you have a "Part-Whole" tree structure? → Composite.
  4. Need to add features like "Onion Skins" at runtime? → Decorator.
  5. Need a "Help Desk" for a messy, multi-service system? → Facade.
  6. Need a "Gatekeeper" to control or cache access? → Proxy.
  7. Are you running out of RAM because of too many objects? → Flyweight.

4. Comparisons That Matter

PairWhy they look similarHow to choose
Bridge vs AdapterBoth put an interface between two piecesBridge separates two dimensions you expect to grow. Adapter makes an existing API fit after the mismatch is already there.
Bridge vs StrategyBoth use composition through an interfaceBridge has two independently growing sides, such as message type × channel. Strategy swaps algorithms for one job.
Decorator vs ProxyBoth wrap an object behind the same interfaceDecorator adds optional behaviour; Proxy controls access, lifetime, location, or caching.
Facade vs MediatorBoth put a central object in the pictureFacade gives outside clients a simpler entrance. Mediator coordinates peers that know and call the mediator.
Composite vs DecoratorBoth hold objects of the same interface inside themselvesComposite is a tree of parts. Decorator is layers around one object.

5. Common Mistakes

  • Using Adapter when you own both APIs and a direct refactor would remove the mismatch.
  • Calling any interface field a Bridge. Without two independently changing dimensions, it is ordinary composition or Strategy.
  • Making a Composite interface so broad that leaves throw UnsupportedOperationException for container-only methods.
  • Building decorator chains where the order changes the result, and not writing that order down.
  • Letting a Facade take on the subsystem's business logic until it becomes a God object.
  • Treating Proxy caching as invisible and ignoring stale data, cache invalidation (removing old entries), or authorization.
  • Using Flyweight before measuring memory. Shared state makes ownership and thread safety harder.

6. Interview Questions

“How do structural patterns differ from behavioural patterns?”

Structural patterns organise how objects are linked and wrapped. Behavioural patterns organise how objects share work and talk. The two overlap in code, so intent matters more than the shape of the diagram.

“What makes Bridge different from ordinary composition?”

Bridge deliberately separates two dimensions that each have several variants and grow independently. The abstraction hands work to the implementation side through a reference, so you avoid one subclass per combination.

“Decorator and Proxy can have the same class diagram. What differs?”

Their intent. A decorator adds responsibilities such as compression or logging. A proxy stands in for the real object to control access, creation, location, caching, or security.

“When is Flyweight worth its complexity?”

After you measure and see that a very large number of objects repeat a lot of unchanging data. Store that intrinsic data once, and pass the changing extrinsic data into each call.

7. Takeaways

Start with the problem that hurts, not the pattern name. Use Adapter for a mismatch, Bridge for two independent axes, Composite for part-whole trees, Decorator for stackable features, Facade for a simpler entrance, Proxy for controlled access, and Flyweight for measured memory pressure. Every one adds an extra layer, so pick the smallest structure that makes a real change easier.

In this topic

Done with this topic?

How well do you know it?

PreviousBridge Pattern: Two Things That Change, Kept Apart
Practise 4 questions