This article explains the Proxy Design Pattern. It is a part of Structural Design Patterns. As the name suggests, it acts as a representation of an object and will basically be the access point to use the original object. This kind of situation is possible when we have resources that may or may not be in the same code or machine or even network. This is similar to the concept of using web services or WCF services to access the required resources.
For an example, we may have a web service API to get the live Stock Market feed or a live Cricket match score. Client applications that need these kinds of data cannot directly access the resources and need to use some kind of intermediate to fetch it. In this case, any API service acts as a Proxy on behalf of the actual resource. This kind of pattern allows not only to control the access to the resources only when required, but also provides security as the client code cannot directly access the resources and must pass through the proxy.
This pattern may sound similar to the adapter, mediator or bridge patterns but it is not. All these patterns play same kind of role by being an intermediate, but the main purpose or the reason for which they are designed, distinguish them from one another. We will explain briefly about the differences between these patterns at the end of this explanation.
What the Proxy Design Pattern is
According to the GoF's definition, this pattern is defined as:
"Provide a surrogate or placeholder for another object to control access to it."
The following is a real-world example.
Let's say that there is a third-party API to get Gold prices in the stock market. These prices are not available for the client application directly. The client application must use a proxy class to get the actual resources, as the main system, that provides this kind of data, cannot allow any third-party to access its database directly. The main point here will be that, the proxy will fetch the current prices from the actual source, only if the client says yes or no. So our client code will be calling the proxy class and the proxy class will get the price from the actual source and send the current price, back to the client code.
Let's convert the preceding real-world example into technical code.
We will be dividing the system into the following components for our implementation of this pattern:
This is the simple interface used to define the abstract resources that we want to access using the proxy class or you can say it contains the abstract functions that we want to share with the client code though the proxy class. So in our case, it will be IPrice with a function to return the prices of Gold, using the GoldPrices class, that will implement this interface.
This is the implementation of the preceding interface or the concrete class. As explained above, in our case, it will be the GoldPrices class that will implement the preceding interface.
- Proxy Class
This is the main class of the system, used by the client code to access the resources. This proxy class will contain the reference to the subject classes, in the form of the interface of the subject.
In our example, it will be the ProxyAPI class. It will have a reference of the IPrice interface. This reference will be further used to access the functions of the subject class or GoldPrice class indirectly.
So our initial code for the preceding structure will be as in the following:
Now we need to write our client code, that will simply create a proxy class instance and call its function. This function will then internally call the actual function of the resources, based on the input from the client code. Finally it will return the output to the client code. So our code will be like as in the following:
So as we see here, it is the proxy that is calling the actual resource. Various kinds of business logic like whether the call is from an authenticated source or not, or any other logic can be added to the proxy layer and control the way the resource is being accessed.
Now, at the start of the explanation, we mentioned about various patterns, that may sound similar to this pattern but are meant to achieve different functionality. So let's explain them briefly here.
Adapter vs Mediator vs Bridge vs Proxy patterns
The purpose of an Adapter Pattern is to solve the incompatibility issues between two interfaces or we can say its like a language converter concept, converting one language sentence to another.
The purpose of a Bridge Pattern is to provide various implementations for a task and each of these implementations can be used in different ways. For example, to send a SMS or email notification to a user and send them in different ways like using a web-service or third-party tools.
The purpose of a Mediator Pattern is to manage the complexity of the system by handling how the components or classes of the system interact with each other. Otherwise, each of these classes will have references to the other classes of the system, in order to call each other. This would result in spider-web type system classes.
Again, a Proxy Design Pattern acts as main point of contact for the resources that should not be available directly to the client code.
A Proxy Design Pattern has various variations that include:
- Virtual Proxy
This type of proxy is created to manage creation of an instance of resources that are very expensive in nature, in other words that consume too much memory or take too much time for accessing the main resource or any other kind of heavy operation.
- Remote proxy
This is similar to the concept of the use of web services or WCF services where the client must access the remote resource on another network, using the proxy class instance.
- Protection proxy
As we explained above, we can create a secure proxy of a resource by adding some kind of authentication for the client code to provide. This is known as a Protection Proxy since the resources are protected by the proxy and the client code must pass the authentication process.
- Smart Proxy
This kind of proxy is used to add some kind of functionality to manage the resources in an efficient manner. For example, in our example, we have added the logic that fetches the resource, only if it is required by the client code. In this way, you can add some kind of singleton pattern so that only one instance of the subject is created or so on.
So depending on our requirements, we may have a combination of one or more of these variations like a protection proxy can be added along with the virtual and remote proxy to authenticate the client making a request for the required data. This was all about the Proxy Design Pattern. Hope you enjoyed reading it.