The Proxy pattern is a structural design pattern that provides an intermediary or placeholder object that controls access to another object. It acts as a substitute or surrogate for the real object and can be used to manage access, perform additional operations, or control the instantiation of the real object.

Key Characteristics:

  • Access Control: Manages access to the real object, which may be expensive to create or require controlled access.
  • Placeholder: Acts as a stand-in for the real object, handling requests and forwarding them as necessary.
  • Additional Functionality: Can add extra functionality or logic (e.g., caching, logging) without modifying the real object.

How It Works:

  • Subject Interface: Defines the common interface for both the RealObject and Proxy. This allows the Proxy to interact with the RealObject and clients transparently.
  • RealObject: The actual object that performs the core functionality. It can be resource-intensive or have complex operations.
  • Proxy: Implements the Subject interface and controls access to the RealObject. It can perform additional operations before or after delegating requests to the RealObject.

Example in PHP:

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

// RealObject
class RealImage implements Image {
    private $filename;

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

    private function loadImage() {
        echo "Loading image: " . $this->filename . "\n";
    }

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

// Proxy
class ProxyImage implements Image {
    private $realImage;
    private $filename;

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

    public function display() {
        if ($this->realImage === null) {
            $this->realImage = new RealImage($this->filename);
        }
        $this->realImage->display();
    }
}

// Client Code
$image1 = new ProxyImage("photo1.jpg");
$image1->display(); // Output: Loading image: photo1.jpg
                    //         Displaying image: photo1.jpg

$image1->display(); // Output: Displaying image: photo1.jpg
  

Explanation:

  1. Subject Interface: Image defines the display() method that both RealImage and ProxyImage will implement.
  2. RealObject: RealImage represents the real object that performs the actual image loading and displaying. It is resource-intensive and only loads the image when required.
  3. Proxy: ProxyImage acts as a proxy to RealImage. It delays the creation of RealImage until it is actually needed (lazy loading) and manages access to it.

Benefits:

  • Lazy Initialization: Delays the creation of resource-intensive objects until they are actually needed.
  • Access Control: Can manage and control access to the real object, adding security or logging.
  • Separation of Concerns: Provides a way to add additional functionality or control without modifying the real object.

Use Cases:

  • Resource Management: When dealing with resource-intensive operations (e.g., loading large files or network resources) that should be delayed or managed.
  • Security: To control access and add security measures to sensitive objects.
  • Logging and Monitoring: To add logging, monitoring, or other cross-cutting concerns without modifying the core logic.

The Proxy pattern is useful for managing access to real objects and adding functionality such as lazy loading, access control, and logging, without altering the real object’s implementation.