What is the Proxy Pattern?
The Proxy Pattern provides a surrogate or placeholder for another object to control access to it. The proxy object implements the same interface as the real subject and acts as an intermediary, managing requests and adding additional functionality such as access control, lazy initialization, logging, or caching.
This pattern is particularly useful when direct access to an object is costly, sensitive, or requires additional handling.
Proxy Pattern Structure
The Proxy Pattern typically involves:
- Subject: Defines the common interface for RealSubject and Proxy.
- RealSubject: The real object that performs the actual work.
- Proxy: Controls access to the RealSubject and may add extra behavior.
Python Implementation Example of Proxy Pattern
Imagine you have a resource-heavy object (like a large image or database connection). The proxy can delay creation or control access to that object.
# Subject Interface
class Subject:
def request(self):
pass
# Real Subject
class RealSubject(Subject):
def request(self):
print("RealSubject: Handling request.")
# Proxy
class Proxy(Subject):
def __init__(self):
self._real_subject = None
def request(self):
if self._real_subject is None:
print("Proxy: Creating RealSubject...")
self._real_subject = RealSubject()
print("Proxy: Delegating request to RealSubject.")
self._real_subject.request()
# Client code
proxy = Proxy()
proxy.request()
proxy.request()
OUTPUT
Proxy: Creating RealSubject...
Proxy: Delegating request to RealSubject.
RealSubject: Handling request.
Proxy: Delegating request to RealSubject.
RealSubject: Handling request.
When to Use the Proxy Pattern
Use the Proxy Pattern when:
- You want to control access to a resource-heavy or sensitive object.
- You need lazy initialization or on-demand loading of expensive resources.
- You want to add logging, caching, or access control without changing the real subject’s code.
- You want to provide a local representative for an object in a different address space (Remote Proxy).