The Proxy Pattern belongs to the structural design pattern family, which focuses on how objects are composed to form larger structures. It introduces a "surrogate" or placeholder object—called the Proxy—that stands in for a RealSubject (the actual object doing the work).
📌 Intent
The proxy controls interaction with the real object and can add new behavior without changing the real object’s code—perfect when:
- You need access control (e.g. only admins allowed to perform certain actions)
- You want to implement lazy loading (create the real object only when it’s actually needed)
- You’re adding features like logging, caching, or monitoring without polluting the original class
🔍 Use Cases
Scenario | Description |
---|---|
Remote Proxy | Represents an object in another address space |
Virtual Proxy | Delays creation of expensive objects |
Protection Proxy | Controls access based on user roles |
Smart Reference Proxy | Adds behavior like logging, caching |
📐 UML Structure
💻 Code Examples
public interface IBankAccount {
void Withdraw(double amount);
}
public class RealBankAccount : IBankAccount {
public void Withdraw(double amount) {
Console.WriteLine($"Withdrew {amount} successfully.");
}
}
public class BankAccountProxy : IBankAccount {
private RealBankAccount _realAccount = new RealBankAccount();
private string _role;
public BankAccountProxy(string role) {
_role = role;
}
public void Withdraw(double amount) {
if (_role == "admin") _realAccount.Withdraw(amount);
else Console.WriteLine("Access Denied.");
}
}
from abc import ABC, abstractmethod
class IBankAccount(ABC):
@abstractmethod
def withdraw(self, amount): pass
class RealBankAccount(IBankAccount):
def withdraw(self, amount):
print(f"Withdrew {amount} successfully.")
class BankAccountProxy(IBankAccount):
def __init__(self, role):
self._real_account = RealBankAccount()
self._role = role
def withdraw(self, amount):
if self._role == "admin":
self._real_account.withdraw(amount)
else:
print("Access Denied.")
🌐 Real-World Examples
Lazy Loading in Entity Framework
- What it is: A form of the Virtual Proxy.
- How it works: Related data is represented by a proxy but not fetched from the database until needed.
- Why it matters: Improves performance by avoiding unnecessary object creation until it's accessed.
Spring AOP Proxies
- What it is: An example of a Smart Proxy in the Spring Framework.
- How it works: Uses dynamic proxies to inject behavior like logging or transactions around core business logic.
- Why it matters: Adds behavior transparently without changing the actual business classes.
Python Decorators as Smart Proxies
- What it is: Decorators act as Smart Proxies by wrapping functions/methods.
- How it works: A decorator intercepts a function call to insert behaviors like caching or access control.
- Why it matters: Keeps code modular and extensible without modifying the original function.
✅ Advantages
- Access control and behavior extension
- Can add logging, caching without modifying the subject
⚠️ Disadvantages
- Increased complexity
- Too many proxies may clutter design
📊 Summary Table
Feature | Proxy Pattern |
---|---|
Purpose | Control access / add behavior |
Types | Remote, Virtual, Protection, Smart |
Key Concept | Surrogate object delegates or filters actions |
UML Components | Subject, RealSubject, Proxy |
🧠 Quiz Preview
Test your understanding of the Proxy Pattern with our interactive quiz on TechWayFit!
🔗 Further Reading
Explore more design patterns and their applications in our Design Patterns Series.