Sometimes we need the ability to control the access to an object. For example, if we need to use only a few methods of some costly objects we’ll initialize those objects when we need them entirely. Until that point, we can use some light objects exposing the same interface as the heavy objects. These light objects are called proxies and they will instantiate those heavy objects when they are really need and by then we’ll use some light objects instead.
This ability to control the access to an object can be required for a variety of reasons: controlling when a costly object needs to be instantiated and initialized, giving different access rights to an object, as well as providing a sophisticated means of accessing and referencing objects running in other processes, on other machines.
Consider for example an image viewer program. An image viewer program must be able to list and display high resolution photo objects that are in a folder, but how often do someone open a folder and view all the images inside. Sometimes you will be looking for a particular photo, sometimes you will only want to see an image name. The image viewer must be able to list all photo objects, but the photo objects must not be loaded into memory until they are required to be rendered.
The intent of this pattern is to provide a placeholder for an object to control references to it.
The participants classes in the proxy pattern are:
Subject – Interface implemented by the realSubject and representing its services. The interface must be implemented by the proxy as well so that the proxy can be used in any location where the RealSubject can be used.
Proxy – Maintains a reference that allows the Proxy to access the RealSubject. Implements the same interface implemented by the RealSubject so that the Proxy can be substituted for the RealSubject. Controls access to the RealSubject and may be responsible for its creation and deletion. Other responsibilities depend on the kind of proxy.
RealSubject – the real object that the proxy represents.
The Proxy design pattern is applicable when there is a need to control access to an Object, as well as when there is a need for a sophisticated reference to an Object. Common Situations where the proxy pattern is applicable are:
Virtual Proxies: delaying the creation and initialization of expensive objects until needed, where the objects are created on demand.
Remote Proxies: providing a local representation for an object that is in a different address space. A common example is Java RMI stub objects. The stub object acts as a proxy where invoking methods on the stub would cause the stub to communicate and invoke methods on a remote object found on a different machine.
Protection Proxies: where a proxy controls access to RealSubject methods, by giving access to some objects while denying access to others.
Smart References: providing a sophisticated access to certain objects such as tracking the number of references to an object and denying access if a certain number is reached, as well as loading an object from database into memory on demand.
Adapter design Pattern – The adapter implements a different interface to the object it adapts where a proxy implements the same interface as its subject.
Decorator design Pattern – A decorator implementation can be the same as the proxy however a decorator adds responsibilities to an object while a proxy controls access to it.