Proxy Design Pattern

Proxy Design Pattern

The Proxy design pattern serves as a mediator to manage access to resource-intensive objects by loading them on demand, thus optimizing performance and resource usage.

The Proxy design pattern is a structural pattern that acts as an intermediary for another object, controlling access and deferring the creation or retrieval of costly resources until they are actually needed. This pattern is particularly beneficial for handling complex objects that require a significant amount of resources, enhancing system security, or adding additional functionality without modifying the original object. The article illustrates the practical use of the Proxy pattern through an example involving a RealImage class, which represents a heavyweight object, and a ProxyImage class that delays the loading of the RealImage until it is necessary to display it. The implementation includes defining a subject interface, creating the real subject, and implementing the proxy class. The proxy class, ProxyImage, holds a reference to the RealImage and ensures that it is loaded only when the display() method is invoked for the first time. Subsequent calls to display() utilize the already loaded image, thus implementing lazy loading and avoiding unnecessary resource consumption.


The Proxy design pattern is a structural pattern that provides a surrogate or placeholder for another object to control access to it. This pattern is useful for managing the complexity of dealing with resource-intensive objects, enhancing security, or adding additional functionalities. In this article, we’ll explore how the Proxy pattern can be used to manage access to a resource-intensive Image object by creating a proxy that loads the image only when necessary. Let's see a practical example to understand the implementation of this pattern.

Implementation

  • Define the Subject Interface: Create an interface that both the real object and the proxy will implement. In our example, this is the Image interface with the display() method.

abstract class Image {
  void display();
}        

  • Implement the Real Subject: Create a concrete class that implements the subject interface. The RealImage class represents the resource-intensive object that loads an image from disk.

class RealImage implements Image {
  late String _fileName;

  RealImage(String fileName) {
    _fileName = fileName;
    loadFromDisk();
  }

  void loadFromDisk() {
    print("Loading $_fileName");
  }

  @override
  void display() {
    print("Displaying $_fileName");
  }
}        

  • Create the Proxy Class: Implement a proxy class that also implements the subject interface and holds a reference to the real object. The ProxyImage class manages access to RealImage, loading it only when display() is called for the first time.

class ProxyImage implements Image {
  RealImage? _realImage;
  late String _fileName;

  ProxyImage(String fileName) {
    _fileName = fileName;
  }

  @override
  void display() {
    if (_realImage == null) {
      _realImage = RealImage(_fileName);
    }
    _realImage!.display();
  }
}        

Usage

  • Instantiate the Proxy: Create an instance of the proxy class (ProxyImage), passing the image filename to its constructor.
  • Display the Image: Call the display() method on the proxy instance. The proxy will load the real image only when this method is called for the first time, and then delegate the call to the RealImage object.
  • Benefit from Lazy Loading: Observe the lazy loading behavior, where the image is loaded only once and subsequent calls to display() do not incur the loading cost.

void main() {
  Image image1 = ProxyImage("image1.jpg");
  Image image2 = ProxyImage("image2.png");

  // Image 1: Image will be loaded from disk when displayed
  image1.display();
  // Image 1: Image will be displayed without reloading from disk
  image1.display();

  // Image 2: Image will be loaded from disk when displayed
  image2.display();
}        

要查看或添加评论,请登录

社区洞察

其他会员也浏览了