---
obj: concept
---
# Proxy Pattern

## **Description:**
The Proxy Pattern is a structural design pattern that provides a surrogate or placeholder for another object to control access to it. It allows you to create a level of indirection to an object, which can be useful for various purposes such as controlling access, lazy loading, logging, monitoring, or adding a security layer to the real object.

**How it's Used:**
1. **Real Subject**: Define an interface that both the real subject and the proxy implement. This interface represents the common operations that the real subject and proxy can perform.
2. **Proxy Class**: Create a proxy class that implements the same interface as the real subject. This proxy class contains a reference to the real subject.
3. **Proxy Methods**: In the proxy methods, you can add additional behavior before or after delegating the request to the real subject. This additional behavior can include access control, logging, or lazy loading.
4. **Client Code**: Clients interact with the proxy object, thinking it's the real subject. The proxy object handles the interaction with the real subject.

## **Example:**
Consider a scenario where you have a large collection of images, and you want to load and display them only when needed to improve performance. You can use the Proxy Pattern to implement lazy loading:

- **Subject Interface**: Define an interface `Image` that represents the common operations for images.
```java
public interface Image {
    void display();
}
```

- **Real Subject**: Create a real subject class `RealImage` that implements the `Image` interface. This class represents the actual image and loads it when required.
```java
public class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("Loading image: " + filename);
    }

    @Override
    public void display() {
        System.out.println("Displaying image: " + filename);
    }
}
```

- **Proxy Class**: Create a proxy class `ProxyImage` that also implements the `Image` interface. This class contains a reference to the real image but loads it lazily when requested.
```java
public class ProxyImage implements Image {
    private RealImage realImage;
    private String filename;

    public ProxyImage(String filename) {
        this.filename = filename;
    }

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}
```

- **Client Code**: In your client code, use the `ProxyImage` class to interact with images. Images are loaded and displayed only when the `display` method is called.
```java
public class Client {
    public static void main(String[] args) {
        Image image1 = new ProxyImage("image1.jpg");
        Image image2 = new ProxyImage("image2.jpg");

        // Images are loaded and displayed when requested
        image1.display();
        image2.display();

        // No additional loading for the already displayed image
        image1.display();
    }
}
```

By using the Proxy Pattern, you can improve the performance of your application by loading and displaying images lazily. The proxy object (`ProxyImage`) handles the loading and displaying of the real images (`RealImage`) as needed. This pattern is also useful for scenarios where you need to control access to sensitive resources, log actions, or add additional functionality to an object without changing its core behavior.