Metadata Card
- Prerequisites: Chapter 7 (SOLID Principles); Chapter 8 (Creational Patterns)
- Estimated Time: 55 minutes
- Core Difficulty: Intermediate
- Completion Milestone: Be able to distinguish the use cases for 7 structural patterns and implement them correctly
Your Progress
You can control how parts are manufactured. But your machine faces new problems: existing gear sets and newly designed bearings have "incompatible interfaces," tree-shaped linkage structures need unified force calculation, functionality needs to be added at runtime.
You stand before the City of Artisans' tool library: "I need a universal adapter — something that can weld different-sized parts together without changing their construction." Your Task
Structural patterns focus on how to compose classes and objects to form larger structures. Each pattern solves a different type of "matching problem": Adapter handles interface incompatibility, Composite unifies tree structures, Decorator adds functionality dynamically, Proxy controls access, Facade simplifies complex subsystems, Bridge separates abstraction from implementation, Flyweight shares fine-grained objects.
Chapter tiers
- Required reading: Adapter, Decorator, Proxy
- Selective: Composite, Facade
- Advanced: Bridge, Flyweight
First Layer: Adapter — Interface Adapter
Makes incompatible interfaces work together, like a power plug adapter.
public class RankingServiceAdapter implements InternalRankingClient {
private final ExternalRankingService external;
public RankingServiceAdapter(ExternalRankingService external) {
this.external = external;
}
@Override
public void submitResult(String matchId, String winner, int score) {
String xml = String.format(
"<match><id>%s</id><winner>%s</winner><score>%d</score></match>",
matchId, winner, score
);
String response = external.submitResult(xml);
if (response.contains("error")) {
throw new RuntimeException("Ranking service error: " + response);
}
}
}Second Layer: Decorator — Add Functionality at Runtime
Allows adding behavior to an object without modifying its class.
Third Layer: Proxy — Surrogate for Another Object
Proxy controls access (rate limiting, lazy loading, caching). Similar structure to Decorator but different intent: Proxy controls access, Decorator adds behavior.
Fourth Layer: Composite — Tree Structure Unified Interface
Treat individual objects and compositions uniformly. A PrizePackage can contain SinglePrizes or other PrizePackages.
Fifth Layer: Facade — Simplified Interface
A unified interface to a set of subsystem interfaces. TournamentFacade provides a simple register() method that coordinates match service, score service, and notification service internally.
Sixth Layer: Bridge — Separate Abstraction and Implementation
Two independent hierarchies — Message types (Normal, Urgent) and Notification channels (SMS, Email). Combine through composition.
Seventh Layer: Flyweight — Share Fine-Grained Objects
Share immutable internal state (tree name, texture) across many objects, keeping mutable external state (position) separate.
Common Pitfalls
Pitfall 1: Using Adapter for semantic transformations, not just interface adaptation. Pitfall 2: Decorator chain order sensitivity — behavior differs when wrapping order changes. Pitfall 3: Proxy and Decorator look structurally identical — distinguish by intent. Pitfall 4: Composite leaf and composite nodes have inconsistent interfaces.
Passing Challenges
- Warm up: Write an Adapter for an external API call.
- Challenge: Add a LoggingProxy (records call duration) instead of LoggingDecorator.
- Observe: Find Decorator examples in frameworks you use — Java
BufferedInputStream, Python@lru_cache.
Traveler's Notes
Seven structural patterns, each solving a composition problem: Adapter translates, Decorator layers, Proxy controls, Composite unifies, Facade simplifies, Bridge separates, Flyweight shares. Your toolbox is growing.
Next: Behavioral Patterns (Chapter 10).