Bird
Raised Fist0
LLDsystem_design~7 mins

Proxy pattern in LLD - System Design Guide

Choose your learning style10 modes available
Problem Statement
Direct access to an object can cause problems like uncontrolled resource usage, security risks, or performance bottlenecks. For example, a heavy object might be created even if it is not always needed, wasting memory and CPU.
Solution
The proxy pattern introduces a placeholder object that controls access to the real object. This proxy can delay creation, add security checks, or cache results before forwarding requests to the real object, improving control and efficiency.
Architecture
Client
→Proxy
↓
RealObject
RealObject

This diagram shows the client interacting with the proxy, which controls access to the real object.

Trade-offs
✓ Pros
→
Delays expensive object creation until needed, saving resources.
→
Adds a layer to enforce access control or security policies.
→
Can cache results to improve performance on repeated requests.
→
Simplifies client code by hiding complex object management.
✗ Cons
→
Adds extra layer of indirection, which can slightly reduce performance.
→
Increases code complexity by introducing additional classes.
→
Requires careful design to avoid proxy becoming a bottleneck.
Use when object creation is costly or resource-intensive, or when you need to add access control, logging, or caching transparently. Suitable for systems with heavy objects or security requirements.
Avoid when objects are lightweight and access control or lazy loading is unnecessary, as the proxy adds unnecessary complexity and overhead.
Real World Examples
Amazon
Uses proxy pattern in its caching layer to delay loading product details until requested, reducing database load.
Netflix
Applies proxy pattern to control access to streaming resources, adding authentication checks before streaming content.
LinkedIn
Uses proxy objects to manage connections to external services, adding retry logic and logging transparently.
Code Example
The before code creates the real image immediately, wasting resources if not displayed. The proxy delays loading until display is called, saving resources and controlling access.
LLD
### Before (no proxy) ###
class RealImage:
    def __init__(self, filename):
        print(f"Loading image from {filename}")
        self.filename = filename
    def display(self):
        print(f"Displaying {self.filename}")

image = RealImage("photo.jpg")
image.display()


### After (with proxy) ###
class RealImage:
    def __init__(self, filename):
        print(f"Loading image from {filename}")
        self.filename = filename
    def display(self):
        print(f"Displaying {self.filename}")

class ProxyImage:
    def __init__(self, filename):
        self.filename = filename
        self.real_image = None
    def display(self):
        if self.real_image is None:
            self.real_image = RealImage(self.filename)
        self.real_image.display()

proxy_image = ProxyImage("photo.jpg")
proxy_image.display()  # Loads and displays
proxy_image.display()  # Displays without loading again
OutputSuccess
Alternatives
Decorator pattern
Decorator adds responsibilities to objects dynamically without changing their interface, while proxy controls access to the object.
Use when: Choose decorator when you want to add features to objects without controlling access.
Adapter pattern
Adapter changes the interface of an object to match what the client expects, proxy keeps the same interface but controls access.
Use when: Choose adapter when you need to make incompatible interfaces work together.
Summary
Proxy pattern controls access to an object by using a placeholder.
It helps delay expensive object creation and add security or caching.
It adds a layer of indirection that can improve resource management.

Practice

(1/5)
1.

What is the main purpose of the Proxy pattern in system design?

easy
A. To replace the real object permanently with a new one
B. To control access to an object by using a placeholder
C. To directly modify the real object's data
D. To create multiple instances of an object

Solution

  1. Step 1: Understand the Proxy pattern role

    The Proxy pattern acts as a stand-in or placeholder to control access to another object.
  2. Step 2: Compare options with the pattern definition

    Only To control access to an object by using a placeholder correctly describes controlling access using a placeholder, which matches the Proxy pattern.
  3. Final Answer:

    To control access to an object by using a placeholder -> Option B
  4. Quick Check:

    Proxy pattern = control access placeholder [OK]
Hint: Proxy controls access via placeholder, not object creation [OK]
Common Mistakes:
  • Confusing Proxy with Singleton pattern
  • Thinking Proxy modifies the real object directly
  • Assuming Proxy replaces the real object permanently
2.

Which of the following is the correct way to declare a proxy class that implements the same interface as the real object?

interface Image {
    void display();
}

// Which proxy class declaration is correct?
easy
A. interface ImageProxy implements Image { void display(); }
B. class ImageProxy extends Image { void display() { /* control access */ } }
C. class ImageProxy { void display() { /* control access */ } }
D. class ImageProxy implements Image { void display() { /* control access */ } }

Solution

  1. Step 1: Recall interface implementation syntax

    In many languages, a class implements an interface using the 'implements' keyword, not 'extends'.
  2. Step 2: Check each option's correctness

    class ImageProxy implements Image { void display() { /* control access */ } } correctly declares a class implementing the interface. class ImageProxy extends Image { void display() { /* control access */ } } wrongly uses 'extends' for an interface. class ImageProxy { void display() { /* control access */ } } misses interface implementation. interface ImageProxy implements Image { void display(); } wrongly declares an interface implementing another interface.
  3. Final Answer:

    class ImageProxy implements Image { void display() { /* control access */ } } -> Option D
  4. Quick Check:

    Proxy class implements interface = class ImageProxy implements Image { void display() { /* control access */ } } [OK]
Hint: Proxy class must implement interface, not extend it [OK]
Common Mistakes:
  • Using 'extends' instead of 'implements' for interfaces
  • Not implementing the interface at all
  • Declaring proxy as an interface instead of a class
3.

Given the following code snippet, what will be the output?

class RealImage {
    void display() { System.out.println("Displaying real image"); }
}

class ProxyImage {
    RealImage realImage;
    void display() {
        if (realImage == null) {
            realImage = new RealImage();
        }
        realImage.display();
    }
}

ProxyImage proxy = new ProxyImage();
proxy.display();
proxy.display();
medium
A. Displaying real image Displaying real image
B. Displaying real image
C. No output
D. NullPointerException

Solution

  1. Step 1: Analyze the first call to display()

    Since realImage is null initially, it is created and then display() prints "Displaying real image".
  2. Step 2: Analyze the second call to display()

    realImage is no longer null, so display() is called directly again, printing the same message.
  3. Final Answer:

    Displaying real image Displaying real image -> Option A
  4. Quick Check:

    Lazy loading calls display twice [OK]
Hint: Proxy lazy loads real object, so display prints twice [OK]
Common Mistakes:
  • Assuming display prints only once
  • Expecting NullPointerException due to uninitialized realImage
  • Thinking proxy suppresses output
4.

Identify the error in the following proxy implementation and select the fix:

class Proxy {
    RealObject real;
    void request() {
        real.request();
    }
}
medium
A. Remove the proxy and call RealObject directly
B. Change method name from request() to execute()
C. Initialize 'real' before calling request()
D. Make 'real' a static variable

Solution

  1. Step 1: Identify the problem in the code

    The proxy calls real.request() but 'real' is never initialized, causing a NullPointerException.
  2. Step 2: Determine the correct fix

    Initializing 'real' before calling request() ensures the real object exists and avoids errors.
  3. Final Answer:

    Initialize 'real' before calling request() -> Option C
  4. Quick Check:

    Uninitialized real causes error; initialize it [OK]
Hint: Always initialize real object before proxy calls it [OK]
Common Mistakes:
  • Ignoring null initialization error
  • Changing method names unnecessarily
  • Removing proxy defeats pattern purpose
5.

You are designing a system where loading a large image file is expensive. You want to use the Proxy pattern to improve performance by loading the image only when needed. Which of the following design choices best applies the Proxy pattern for this scenario?

hard
A. Create a proxy class that holds the image filename and loads the real image only when display() is called
B. Load the real image immediately when the proxy is created to avoid delays
C. Use a proxy that duplicates the image data to speed up access
D. Replace the real image with a smaller thumbnail permanently

Solution

  1. Step 1: Understand the problem context

    Loading large images is expensive, so delaying loading until necessary improves performance.
  2. Step 2: Match design choices to Proxy pattern benefits

    Create a proxy class that holds the image filename and loads the real image only when display() is called uses lazy loading by deferring real image loading until display() is called, which fits Proxy pattern use.
  3. Final Answer:

    Create a proxy class that holds the image filename and loads the real image only when display() is called -> Option A
  4. Quick Check:

    Lazy loading with proxy = Create a proxy class that holds the image filename and loads the real image only when display() is called [OK]
Hint: Proxy delays expensive load until needed (lazy loading) [OK]
Common Mistakes:
  • Loading real object immediately defeats proxy benefit
  • Duplicating data wastes resources
  • Replacing with thumbnail changes object behavior
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