0
0
LLDsystem_design~7 mins

Proxy pattern in LLD - System Design Guide

Choose your learning style9 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.