--- 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.