Proxy Pattern

What is the Proxy pattern?

Proxy means: put an object in front of another object so you can control access to it.

The proxy implements the same interface as the real object. Callers talk to the proxy as if it were the real thing. Behind the scenes, the proxy decides when to create the real object, whether the caller is allowed to proceed, or whether to cache a result, before forwarding the call.

In plain words: the proxy is a door. The room behind the door is the real object. Callers knock on the door; the door decides what happens next.

This differs from Decorator. A decorator’s main job is to add behavior. A proxy’s main job is to control access — even when it also happens to add a little behavior along the way.


The problem it solves

Suppose you have an image that is expensive to load.

If a gallery constructs a RealImage for every thumbnail, users pay the load cost even for photos they never open. You want the same Image interface, but with lazy loading baked into how the object is reached.


A virtual proxy: load only when needed

A virtual proxy delays creation of the expensive object until the first real use.

From the caller’s point of view, photo is just an Image. The proxy hides the timing of the expensive work.


Other common kinds of proxy

People use the same shape for several jobs:

  • Protection proxy. Check permissions before forwarding. A document editor might allow reading for everyone, but only editors can call save().
  • Remote proxy. Look local, talk over the network. The caller thinks it has a normal object; the proxy sends the request to another machine.
  • Caching / smart proxy. Remember a previous result, count references, or write an audit line before calling through.

The shared idea is always the same: same interface, controlled access, real object somewhere behind the proxy.


A protection proxy example

Callers still depend on Document. The proxy enforces the rule without changing RealDocument.


When it helps

Use a proxy when the object’s access path needs special handling: expensive creation, security checks, remote calls, or light caching around an existing type.

It also helps when you want callers to keep using a familiar interface while you change what happens underneath.


When it hurts

Do not add a proxy “just in case.” An extra layer that always forwards with no real policy makes the code harder to follow.

Be careful when the proxy changes behavior enough to surprise callers — silently failing, or caching mutable data without a clear invalidation rule. A good proxy stays honest: same interface, predictable semantics, documented side effects.

If your goal is mainly to stack optional features, look at Decorator first. If your goal is to simplify a whole subsystem with many classes, look at Facade.


Practical tips

  • Give the proxy the same interface as the real subject.
  • Keep business rules in the real object; let the proxy handle access, timing, and transport.
  • For lazy loading, create the real object once and reuse it.
  • Name the proxy after its job (ImageProxy, CachingProductRepository) so readers know why it exists.
  • Document the cost — “first display() hits disk.”

Check your understanding

What is Proxy, in one sentence?
An object that stands in for another and controls how callers reach it.

How is it different from Decorator?
Decorator focuses on adding behavior; Proxy focuses on controlling access, though both wrap an object.

What is a virtual proxy?
A proxy that delays creating or loading the real object until it is needed.

Why keep the same interface?
So callers do not need to know they are talking to a stand-in.


What to learn next

Next: Composite Pattern — treat single items and groups of items through one interface.