Proxy

AKA: Surrogate

When object construction requires more resources than you can afford, systems slow down and become unresponsive. Systems avoid this using tactics such as lazy evaluation or loading-on-demand. But this means objects then have two jobs. They must be the thing they need to be but also the not-yet-realised versions of themselves.

Other times, an object might have methods requiring the acquisition of resources, but in hindsight, those specific methods are not necessary to achieve your goal. For example, if you want to know the size of an image, you don’t need to load the whole file, only the header. However, adding the capacity to partially load a file is a new feature not everyone wants.

Or perhaps what you need from the API is a caching mechanism. As you can see, the Proxy pattern handles quite a few problems.

A Proxy is an object which takes some responsibility away from the concrete object, the RealSubject. It acts as a stand-in, like an Adapter, but adjusts behaviour like a Decorator. Instead of modifying the API or adding features, it intercepts calls directed at the RealSubject and manages the workload and lifetime of the RealSubject.

Proxy

A Proxy can respond faster or more cheaply than the complete object it represents. You can tune it to the client’s needs rather than write for completeness or correctness. Examples include image placeholders, remote service proxies, pre-validating before beginning a transaction, quick estimates or rough versions of the expensive transformations. In image processing, for example, a Proxy could provide an instantaneous blocky estimate of a radial blur or a preview of resource-intense filters.

The GoF book mentions four types of proxy:

  • Remote proxy: a stand-in for some object in another address space, potentially even on a different host.
  • Virtual proxy: e.g. the lazy loading image object.
  • Protection proxy: adding access control to an object.
  • The smart reference is a proxy for objects like a smart pointer, potentially with resource reference for load on demand and for mutable state, handling locking of the object.

A Proxy is one of the best uses of the object-oriented paradigm. Swapping out a whole set of behaviours for another is possible in non-OO languages, but the simultaneous change of behaviour and data representation is smoother in OO. A virtual proxy removes the decision-making process for resource handling, decoupling the concern of when and how to handle the required system calls. In most other paradigms, this involves local adjustment to support the feature.

“The RealSubject is not available. How can I help you?”