Structural patterns: shaping object graphs
Structural patterns solve how objects compose without rewriting existing code. They appear constantly in LLD when you integrate legacy APIs, add cross-cutting behavior, or simplify a messy subsystem.
| Pattern | Intent | LLD example |
|---|---|---|
| Adapter | Make incompatible interface work | Wrap third-party LegacyPaymentGateway as PaymentMethod |
| Decorator | Add behavior dynamically, same interface | GzipDecorator wraps DataSource.read() |
| Facade | Simplify a complex subsystem | LibraryFacade.checkout() hides catalog + inventory + fines |
| Proxy | Control access to a real object | Lazy-loading ImageProxy, access-controlled BankAccountProxy |
Decorator vs inheritance
Both add behavior, but Decorator wraps at runtime and stacks (new Encryption(new Gzip(file))). Subclassing freezes the combination at compile time — GzipEncryptedFile multiplies classes exponentially.
Facade vs God object
A Facade is a thin coordinator with no business logic — it delegates. If LibraryFacade starts calculating fines itself, it becomes a God object. Keep domain rules in domain classes; Facade only orchestrates calls.
Composite (brief)
Composite treats individual and group objects uniformly (File and Directory both implement FileSystemNode). Useful for tree structures (org charts, menu hierarchies) — pair with Iterator for traversal. Less frequent than Decorator in LLD but worth naming if the problem is inherently recursive.
Senior-level signal
When wrapping, state the interface contract: "Decorator implements DataSource so callers can't tell whether they're reading raw or gzipped bytes — LSP holds." For Proxy, distinguish virtual (lazy), protection (permissions), and remote (RPC) — naming the variant shows production awareness.
Where this goes next
Behavioral Patterns covers pluggable algorithms and event-driven flows — Strategy, Observer, Command, and State — the highest-frequency patterns in FAANG LLD loops.
Further Reading
Practice Tasks (Optional)
Design or implement locally in any language — no autograding. Focus on class structure, extensibility, and being able to explain trade-offs out loud.
- Decorator for a data source25m
Design: DataSource interface with read(). Concrete FileDataSource. Add GzipDecorator and EncryptionDecorator that wrap any DataSource. Sketch UML or boxes-and-arrows.