Also known as Surrogate.
Provide an interface to a particular ressource to control access to it.
The ressource may be remote, expensive to construct or require any kind of additional functionality (such a logging for example).
Note : The interface provided by the Proxy should look exactly the same as the Object. (Well, it can provide additional enhancements, but it has to implement the object interface.)
Note : There are many different types of Proxy :
- Virtual proxy
- Protection proxy
- Remote proxy
- ...
You should use the Proxy pattern in the following cases :
- You want to add access restrictions to an object (make it read-only, add a logging control operation...) (Protection proxy)
- You have an heavyweight service object that wastes system ressources by being always up and you want to provide some kind of Lazy initialisation to that object (Virtual proxy)
- You want to provide local execution of a remote service - Your service object is therefore located on a remote server. (Remote proxy)
Participants
- Proxy :
- Maintains a reference to the RealSubject (proxied object).
- Provide an identical interface to Subject's.
- Controls access to the RealSubject.
- Subject : Degines the common interface of RealSubject and Proxy so that the Proxy can be used anywhere the RealSubject is needed.
- RealSubject : The real object represented by the Proxy.
- Client : Uses the Proxy as if it was the RealSubject. The Client might actually not even know about it.
Notes about the Proxy object
- If the interface of both Subject and RealSubject are the same, then Proxy might yield a reference to Subject instead.
- The Proxy might also be responsible of the Life cycle of the RealSubject.
- Additional responsabilities can depend of the kind of proxy :
- Remote proxy : Encoding requests.
- Virtual proxy : Caching additional informations about the RealSubject so that they can postpone accessing it.
- Protection proxy : Permissions checking.
How to implement
- Create the Proxy class with a field to a RealSubject reference. The Proxy might actually own the RealSubject and be responsible of its creation/deletion, but not necessarily.
- Implement the RealSubject interface (or Subject's one, see the Notes above) into your Proxy class. In most cases, a consequent part of the hard-work is delegated to the underlying RealSubject.
- Consider introducing a creation method that decides whether the client gets a proxy or a real service. (using a Factory for example).
Note : You also might want to use lazy initialization for the service object.
Note : UML class diagram taken from here
Pros
- Simplifies client : Hide implementations details from clients.
- Open/Closed principle: You can easily introduce new proxies without changing the service or client.
Cons
- Complexity : Increases the number of classes (as the majority of Design patterns).
- The response from teh service might get delayed.
- Dependency inversion principle: Usually, the Proxy has to know the concrete class of the RealSubject.
Did you know ?
- Smart pointers from the standard library is an example of the Proxy design pattern.
Indeed, consider the following code snippet :
aPointer->aFunction(); *aPointer = aValue;
- There is no way you can know whether
aPointer
is a raw pointer or a smart pointer. - That is because smart pointers provide an interface to access an underlying raw pointer that looks just like the interface of a raw pointer.
- There is no way you can know whether
Ressources
Here are some usefull ressources :
- The w3sdesign is really clear and concise !
- A blog article with examples of :
- Property Proxy
- Virtual Proxy
- Communication Proxy
- A Refactoring guru article.