What is Proxy pattern?

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 proxy object that acts as an intermediary or substitute for the actual object, providing additional functionality or controlling the access to the original object.

The Proxy pattern is useful in situations where direct access to an object may not be feasible or desirable. The proxy object allows you to perform operations before or after accessing the real object, such as logging, caching, or authorization checks.

Key components of the Proxy pattern:

  1. Subject/Interface: This represents the common interface or abstract class that both the proxy and real object implement. It defines the operations or methods that the client can invoke.
  2. Real Subject/Real Object: This is the real object that the proxy represents. It implements the subject/interface and contains the actual business logic.
  3. Proxy: The proxy acts as a surrogate for the real object. It implements the subject/interface and delegates the requests from the client to the real object. The proxy can add additional functionality, perform pre- or post-processing tasks, or control the access to the real object.

Benefits and use cases of the Proxy pattern:

  1. Remote access and distributed systems: The Proxy pattern is commonly used in distributed systems or remote method invocation scenarios, where the proxy object handles communication and marshalling between the client and the remote object.
  2. Access control and security: Proxies can enforce access control and provide an additional layer of security by performing authentication or authorization checks before allowing access to the real object.
  3. Lazy initialization and optimization: Proxies can delay the creation or initialization of expensive objects until they are actually needed. This can improve performance by avoiding unnecessary object creation or initialization.
  4. Caching and memoization: Proxies can cache results or data from the real object and return them directly for subsequent requests, reducing the processing time and improving efficiency.
  5. Logging and auditing: Proxies can add logging or auditing capabilities to record the interactions with the real object, providing a way to track and analyze the usage of the object.

Example of the Proxy pattern in Java:

// Subject/Interface
public interface Image {
    void display();
}

// Real Subject/Real Object
public class RealImage implements Image {
    private String filename;

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

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

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

// Proxy
public class ImageProxy implements Image {
    private String filename;
    private RealImage realImage;

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

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

// Usage:
Image image = new ImageProxy("image.jpg");
image.display();

In the above example, the Image interface represents the common interface for both the real image and the proxy. The RealImage class is the real object that loads and displays the image from disk.

The ImageProxy class is the proxy that acts as a surrogate for the real image. It lazily initializes the RealImage object and delegates the display() method call to the real image when necessary.

In the usage example, the client creates an Image object using the ImageProxy. When the display() method is called on the proxy, it checks if the real image has been initialized. If not, it creates an instance of the RealImage class. The display() method is then invoked on the real image to display the image.

The Proxy pattern allows you to control access to objects and add additional functionality or behavior around them. It provides a level of indirection between the client and the real object, enabling optimization, security, or other features without changing the client’s code.

error: Content is protected !!