Design patterns: Proxy

Mauto 3 min

The Proxy Pattern is a structural design pattern that provides a “stand-in” or “surrogate” to control access to an object. The proxy acts as an intermediary between the client and the actual (real) object, letting you add control logic without modifying the original object. It is commonly used to control access, defer initialization, or manage expensive resources.

Characteristics of the Proxy pattern

  1. Access Control: It lets you manage or restrict access to an object that is sensitive or expensive to create, making it possible to add security or authentication mechanisms.
  2. Lazy Initialization: The proxy lets you defer creation of the “real” object until it’s actually needed, optimizing resource usage.
  3. Adding Extra Behavior: The Proxy Pattern lets you add extra behavior or logic (such as logging, caching, or transaction management) without modifying the original object.
  4. Better Performance: It can improve performance by avoiding loading heavy objects until they are needed, as with remote objects or objects with complex initialization processes.
  5. Separation of Control Logic: It keeps the control logic separate from the real object, improving maintainability and code clarity, since access behavior can be changed without changing the original object.

Use Case

Suppose we have a system that handles high-resolution images, but we want to load an image only when it is actually requested, avoiding expensive loading operations at startup.

PHP Example

// Common interface
interface Image {
    public function display();
}

// Class representing the real image
class RealImage implements Image {
    private $filename;

    public function __construct($filename) {
        $this->filename = $filename;
        $this->loadImageFromDisk();
    }

    private function loadImageFromDisk() {
        echo "Loading image from disk: {$this->filename}\n";
    }

    public function display() {
        echo "Displaying image: {$this->filename}\n";
    }
}

// Proxy class that controls access to the real image
class ProxyImage implements Image {
    private $realImage;
    private $filename;

    public function __construct($filename) {
        $this->filename = $filename;
    }

    public function display() {
        // Create the real object only when needed (lazy loading)
        if ($this->realImage == null) {
            $this->realImage = new RealImage($this->filename);
        }
        $this->realImage->display();
    }
}

// Using the Proxy
$image1 = new ProxyImage("high_res_photo.jpg");
$image2 = new ProxyImage("another_photo.jpg");

// The image is loaded only when requested
$image1->display(); // Loads the image
$image1->display(); // Does not reload the image
$image2->display(); // Loads another image

Explanation

  • RealImage is the real object that represents a high-resolution image and simulates an expensive load.
  • ProxyImage is the proxy that controls access to the real object. In this example it uses “lazy” loading, meaning it loads the image only when the display() method is called for the first time.
  • The client always interacts with the Image interface and doesn’t need to know whether it’s using the real image or the proxy. This makes the code more flexible.

Conclusion

The Proxy Pattern is useful for optimizing access to, and management of, objects that are sensitive or expensive to create. It is especially beneficial in use cases such as lazy loading, remote object management, access control, and caching.

BACK TO THE GUIDE

Copiato