Bird
Raised Fist0
LLDsystem_design~7 mins

When to use which structural pattern in LLD - System Design Guide

Choose your learning style10 modes available
Problem Statement
Without clear guidance on when to apply each structural pattern, developers often misuse them, leading to rigid, hard-to-maintain code or overcomplicated designs that slow down development and increase bugs.
Solution
This guidance explains the specific situations where each structural pattern fits best by matching common design problems to the pattern's strengths. It helps developers choose the right pattern to organize code components effectively, improving flexibility and maintainability.
Architecture
Client Code
→Structural
↓
Adapter

This diagram shows client code interacting with different structural patterns to organize system components based on specific needs.

Trade-offs
✓ Pros
→
Helps select the most suitable pattern for a given design problem, improving code clarity.
→
Prevents misuse of patterns that can cause unnecessary complexity or rigidity.
→
Encourages maintainable and scalable system architecture by matching patterns to context.
✗ Cons
→
Requires understanding of multiple patterns and their trade-offs, which can be overwhelming for beginners.
→
Choosing the wrong pattern despite guidance can still lead to poor design.
→
Over-reliance on patterns may cause over-engineering if not carefully considered.
Use when designing systems that require flexible component organization, such as adapting interfaces, adding responsibilities dynamically, composing objects into tree structures, or controlling access to objects. Especially useful when system complexity grows beyond simple class relationships.
Avoid when the system is very simple with minimal component interaction, or when performance constraints prohibit additional abstraction layers introduced by patterns.
Real World Examples
Netflix
Uses the Adapter pattern to integrate legacy video encoding libraries with new streaming APIs, allowing seamless upgrades without rewriting existing code.
Amazon
Applies the Composite pattern in its product catalog to represent categories and subcategories uniformly, enabling flexible navigation and management.
LinkedIn
Employs the Decorator pattern to add features like logging and security checks dynamically to service calls without changing core logic.
Code Example
The before code tightly couples Client to OldService's specific method. The after code introduces an Adapter that translates Client's expected method to OldService's method, allowing Client to work with different services without changes.
LLD
### Before: No pattern, direct class usage
class OldService:
    def specific_request(self):
        return "Old service response"

class Client:
    def __init__(self):
        self.service = OldService()
    def do_work(self):
        return self.service.specific_request()

client = Client()
print(client.do_work())

### After: Adapter pattern applied
class OldService:
    def specific_request(self):
        return "Old service response"

class ServiceAdapter:
    def __init__(self, old_service):
        self.old_service = old_service
    def request(self):
        return self.old_service.specific_request()

class Client:
    def __init__(self):
        self.service = ServiceAdapter(OldService())
    def do_work(self):
        return self.service.request()

client = Client()
print(client.do_work())
OutputSuccess
Alternatives
Facade
Provides a simplified interface to a complex subsystem rather than reorganizing object relationships.
Use when: When you want to hide subsystem complexity behind a simple API for ease of use.
Bridge
Separates abstraction from implementation to allow independent variation, unlike structural patterns focused on object composition.
Use when: When you need to vary both abstractions and implementations independently.
Summary
Choosing the right structural pattern depends on the specific design problem and system complexity.
Structural patterns help organize code to improve flexibility, maintainability, and scalability.
Misusing patterns can cause complexity or rigidity, so understanding when to use each is crucial.

Practice

(1/5)
1. Which structural pattern is best suited for representing part-whole hierarchies like folders and files in a system?
easy
A. Facade pattern
B. Composite pattern
C. Proxy pattern
D. Decorator pattern

Solution

  1. Step 1: Understand the problem context

    Part-whole hierarchies like folders and files form tree structures where each node can be a composite or a leaf.
  2. Step 2: Match the pattern to the structure

    The Composite pattern is designed to treat individual objects and compositions uniformly, perfect for tree-like structures.
  3. Final Answer:

    Composite pattern -> Option B
  4. Quick Check:

    Tree structures = Composite pattern [OK]
Hint: Tree or hierarchy? Use Composite pattern [OK]
Common Mistakes:
  • Confusing Decorator with Composite
  • Using Proxy for hierarchy management
  • Choosing Facade for internal structure
2. Which pattern should you use if you want to add responsibilities to objects dynamically without changing their class?
easy
A. Proxy pattern
B. Facade pattern
C. Composite pattern
D. Decorator pattern

Solution

  1. Step 1: Identify the need to add features dynamically

    When you want to add new behavior to objects at runtime without altering their class, you need a flexible pattern.
  2. Step 2: Select the pattern that wraps objects

    The Decorator pattern wraps objects to add responsibilities dynamically, without changing the original class.
  3. Final Answer:

    Decorator pattern -> Option D
  4. Quick Check:

    Add features dynamically = Decorator [OK]
Hint: Add features on the fly? Use Decorator [OK]
Common Mistakes:
  • Choosing Proxy instead of Decorator
  • Using Facade to add features
  • Confusing Composite with Decorator
3. Consider a system where you want to control access to a resource and add lazy loading. Which structural pattern fits best?
class ResourceProxy {
  constructor() {
    this.resource = null;
  }
  access() {
    if (!this.resource) {
      this.resource = new RealResource();
    }
    return this.resource;
  }
}
medium
A. Proxy pattern
B. Decorator pattern
C. Composite pattern
D. Facade pattern

Solution

  1. Step 1: Analyze the code behavior

    The code delays creating the real resource until it is accessed, controlling access and adding lazy loading.
  2. Step 2: Identify the matching pattern

    This behavior matches the Proxy pattern, which controls access to another object and can add lazy initialization.
  3. Final Answer:

    Proxy pattern -> Option A
  4. Quick Check:

    Control access + lazy load = Proxy [OK]
Hint: Control access or lazy load? Use Proxy [OK]
Common Mistakes:
  • Confusing Proxy with Decorator
  • Using Facade for access control
  • Choosing Composite for resource control
4. You have a complex subsystem with many classes. You want to provide a simple interface to clients. Which pattern should you use? A developer wrote this code but clients still see complex calls:
class ComplexSystem {
  operationA() {}
  operationB() {}
  operationC() {}
}

class SimpleInterface {
  constructor() {
    this.system = new ComplexSystem();
  }
  simpleOperation() {
    this.system.operationA();
    this.system.operationB();
    this.system.operationC();
  }
}
What is the likely mistake?
medium
A. They did not hide the ComplexSystem instance properly
B. They used Proxy instead of Facade
C. They used Composite instead of Facade
D. They forgot to add Decorator to SimpleInterface

Solution

  1. Step 1: Understand Facade pattern purpose

    Facade provides a simple interface hiding complex subsystem details from clients.
  2. Step 2: Identify the mistake in code usage

    If clients still see complex calls, likely the ComplexSystem instance is exposed or clients bypass the Facade.
  3. Final Answer:

    They did not hide the ComplexSystem instance properly -> Option A
  4. Quick Check:

    Facade hides complexity = hide subsystem [OK]
Hint: Facade hides complexity; don't expose subsystem [OK]
Common Mistakes:
  • Confusing Proxy with Facade
  • Exposing subsystem objects to clients
  • Using Decorator to simplify interface
5. You are designing a graphic editor. You want to represent shapes that can be simple (circle, square) or groups of shapes. You also want to add features like border color dynamically and control access to some shapes. Which combination of structural patterns should you use?
hard
A. Facade for groups, Proxy for features, Composite for access control
B. Decorator for groups, Composite for features, Facade for access control
C. Composite for groups, Decorator for features, Proxy for access control
D. Proxy for groups, Facade for features, Decorator for access control

Solution

  1. Step 1: Match patterns to requirements

    Groups of shapes form tree structures best handled by Composite. Adding features dynamically fits Decorator. Controlling access fits Proxy.
  2. Step 2: Combine patterns correctly

    Use Composite for shape groups, Decorator to add border color dynamically, and Proxy to control access to shapes.
  3. Final Answer:

    Composite for groups, Decorator for features, Proxy for access control -> Option C
  4. Quick Check:

    Groups=Composite, Features=Decorator, Access=Proxy [OK]
Hint: Groups=Composite, Features=Decorator, Access=Proxy [OK]
Common Mistakes:
  • Mixing Facade with group representation
  • Using Proxy for adding features
  • Confusing Decorator with access control
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard