Open viphat opened 6 years ago
The intent of the proxy-pattern is to provide a placeholder for another object to control access to it. It introduces an additional level of indirection. There are several reasons why you would want to do this, hence there are several uses for this pattern.
One reason for controlling access to an object is to defer the full cost of its creation and initialization until we actually need to use it. Consider a document editor that can embed graphical objects in a document. It isn't necessary to load all pictures when the document is opened, because not all of these objects will be visible at the same time
So we could think about loading each picture on demand, which occurs when an image becomes visible in the document. But what do we put in the document instead of the image? And how can we hide that the pictures are created on demand?
The solution is to use another object, a proxy, in place of an image. The proxy acts like an image and loads the picture when it's required.
The proxy loads and creates the real image just when the document editor requests for showing that image by invoking its draw-method. The proxy then loads the image and forwards the request to it.
This was one usage of a proxy, but there are many more. Some have their own names, depending on their responsibility:
Superficially, the proxy is very similar to the adapter: One object stands in for another. But the proxy does not change the interface; the interface of the proxy is exactly the same as the interface of its subject. Instead of trying to transform the interface of that inner object in the same way that an adapter does, the proxy tries to control access to it.
The intent of the Proxy Pattern is to:
Proxies as defined by the Proxy Pattern, are deceptively simple, very useful, and highly flexible. The central premise of the Proxy Pattern is that whenever you need to control the access to an object, a Proxy object will do the trick. Sitting between a caller (a Client) and a receiver (the Subject), the Proxy class of the Proxy Pattern can provide protection, hide complexity, or delay expensive actions.
Protection proxies: Sometimes, in the interest of security, it is prudent to place a proxy object in front of an object in order to add additional security. Such proxies are known as protection proxies.
Virtual proxies: Other times, it is wise to delay the creation of expensive objects until they are absolutely needed. Especially in cases where such instantiation may not needed at all. A great example of this type of proxy is the
ActiveRecord::Associations::CollectionProxy
in Rails. Such proxies are known as virtual proxies.Remote proxies - Occasionally, it is necessary to locally represent an object that exists on a remote system, hiding the complexity of traversing the network from the local client. Such proxies are known as remote proxies.
Using method_missing for proxied methods
In Ruby, it can sometimes be quite helpful to leverage the
method_missing
method to forward all methods not defined on the proxy to the subject being proxied. In cases where methods are treated uniformly across the proxy interface, doing so can save quite a great deal of time and effort. It can also protect the proxy from future additions to the proxied subject.Proxies vs Decorators
You may have noticed that a proxy sometimes uses the same implementation pattern as a decorator. In such cases, the difference between a decorator and a proxy lies in the intent. A decorator is intent on adding additional responsibilities to an object, whereas a proxy controls access to an object.
Proxies vs Adapter
An adapter provides a different interface to the object that it adapts, whereas a proxy provides either the same interface as its subject, or a subset of the interface of its subject.
Source