2.8 Proxy
The Proxy pattern puts a stand-in object in front of the real object to control access to it. The proxy and the real object share one interface, so the client thinks it uses the real object directly while every request actually passes through the proxy first.
A proxy can insert control logic before and after "forwarding the request," yielding several common types:
- Virtual proxy: defers creating an expensive object (lazy loading).
- Protection proxy: checks permissions before forwarding.
- Remote proxy: turns a local call into a network request (an RPC stub).
- Smart reference: adds counting, locking, logging, etc. on access.
In the lazy-loading lab below, the real high-res image is heavy; the proxy shows a placeholder and only creates/loads it on your first real render(), then caches it.
Protection proxy: check at the door
class GuardProxy implements Service {
private final Service real;
private final User user;
public void delete() {
if (!user.isAdmin()) throw new AccessDeniedException(); // check first
real.delete(); // then forward
}
}The real object real need not care "who is calling"; authorization is cleanly isolated in the proxy. The access-control lab below lets you switch roles (guest / user / admin) and try actions, watching the proxy allow or block.
Proxy vs Decorator vs Adapter
These three have similar structure (all wrap an object); the difference is entirely intent:
| Pattern | Intent | Interface |
|---|---|---|
| Adapter | Convert interfaces so incompatible parts cooperate | Changes the interface |
| Decorator | Enhance functionality, stack responsibilities | Keeps the interface |
| Proxy | Control access, not enhance functionality | Keeps the interface |
One-line distinction: a decorator makes the object do more; a proxy decides whether the object may be used.