Design Patterns: Proxy
Published: 2023-11-11 23:03:47

The proxy design pattern is a structural design pattern where a class often known as the intermediary represents the functionality of another class. the main object is known as the **real object** while the intermediary is known as the **proxy**. The proxy when invoked can access the real object behind the scenes.

**Motivation**
When creating an object is resource-intensive or requires significant overhead. It can be inefficient to instantiate these objects when they might not be needed. Or, take into account scenarios where you need to restrict access to an object for security, logging, or other reasons. To tackle these situations, the Proxy Pattern can be used without changing the code of the real object.

**Implementation**
A proxy implements the same interface as the real object. Considering a system that fetches images from a server. Here is the **Image** Interface that the proxy (**ProxyImage**) and the real object (**RemoteImage**) implement. 
```
public interface Image{
    void loadImage(String fileName);
}

```
**RemoteImage** is the concrete implementation of the Image interface and the _loadImage_ method fetches the image from the server.
```
public class RemoteImage implements Image {
    @Override
    public void loadImage(String fileName) {
        System.out.println("Fetching From server..." + fileName +".png");
    }
}
```
ProxyImage class is the object that the client interacts with, when rhe _loadImage_ method is called, the system attempts to fetch the image from the cache by checking if the filename exists if it exists it prints the image if the image doesn't exist it fetches from the remote source.

```
public class ProxyImage implements Image {

    private final Map<String, String> imageCache = new HashMap<>();

    @Override
    public void loadImage(String fileName) {
        if (imageCache.containsKey(fileName)) {
            String image = imageCache.get(fileName);
            System.out.println("Loading Image From cache : " + image);
        } else {
            RemoteImage remoteImage = new RemoteImage();
            remoteImage.loadImage(fileName);
            imageCache.put(fileName, fileName + ".png");
            System.out.println("No Image From Cache... Loading From remote" + remoteImage);

        }
    }
}
```
This is the client communicating with the proxy and the output.
```
ProxyImage proxyImageService = new ProxyImage();
        proxyImageService.loadImage("image");
        proxyImageService.loadImage("image");
```


```
Loading From Url...image.png
No Image From Cache... Loading From remoteproxy.RemoteImage@2503dbd3
Loading Image From cache : image.png
```

**Advantages**
1. The proxy can control access to the real object, adding security.
2. The real object is shielded from direct exposure to the system.

**Disadvantages**
1. The code can become more complicated, as you need to introduce additional classes.

**Conclusion**
The proxy pattern regulates access to objects by serving as an intermediary. It adds an abstraction layer that can be applied to access control, logging, and other things. The Proxy Pattern can dramatically improve the architecture and functionality of software systems when implemented wisely.