Structural Pattern
Proxy
Provide a surrogate or placeholder for another object to control access to it.
A stand-in object.
The Proxy pattern puts a stand-in in front of a real object. The proxy has the same interface as the real thing, so callers can't tell the difference — but the proxy can do extra work first, like loading the real object only when needed, checking permissions, or caching results.
bad.py
# Problem: every call loads a huge image from disk — even if unused. class Image: def __init__(self, path): self.pixels = load_from_disk(path) # expensive, always gallery = [Image(p) for p in paths] # loads ALL up front
good.py
# Fix: Virtual Proxy — stand-in that loads the real object on demand. class Image: def __init__(self, path): self.path = path self._pixels = None def display(self): if self._pixels is None: # Lazy load: pay the cost only when first needed. self._pixels = load_from_disk(self.path) show(self._pixels) gallery = [Image(p) for p in paths] # cheap handles gallery[0].display() # loads only this one
Kinds of proxies.
The proxy implements the same Subject interface as the RealSubject and holds a reference to it, forwarding calls after doing its own logic. Common types:
- Virtual proxy — delays creating an expensive object until first use (lazy loading).
- Protection proxy — enforces access control/permissions.
- Remote proxy — represents an object in another address space (RPC/stubs).
- Caching/smart proxy — caches results or adds reference counting, logging, locking.
Relations and real uses.
- vs Decorator — structurally similar (same interface, wraps an object), but Decorator adds behavior while Proxy controls access; a proxy often manages the lifecycle of its subject, a decorator does not.
- vs Adapter — Adapter changes the interface; Proxy keeps it identical.
- Real uses — ORM lazy-loading proxies (Hibernate), Java dynamic proxies / Spring AOP, gRPC/RMI stubs, mocking frameworks, and virtual-memory-style on-demand loading.
- Cost — indirection and potential surprises (a call may trigger network/DB work or fail lazily).