Design patterns: Proxy

Mauto 3 min

Il Proxy Pattern è un design pattern strutturale che fornisce un “sostituto” o “surrogato” per controllare l’accesso a un oggetto. Il proxy rappresenta un intermediario tra il client e il vero oggetto (reale), permettendo di aggiungere logica di controllo senza modificare l’oggetto originale. Viene comunemente utilizzato per controllare l’accesso, ritardare l’inizializzazione o gestire risorse costose.

Caratteristiche del Proxy pattern

  1. Controllo dell’Accesso: Consente di gestire o limitare l’accesso a un oggetto sensibile o costoso da creare, permettendo di aggiungere meccanismi di sicurezza o autenticazione.
  2. Lazy Initialization: Il proxy permette di ritardare la creazione dell’oggetto “reale” fino a quando è effettivamente necessario, ottimizzando l’uso delle risorse.
  3. Aggiunta di Comportamenti Extra: Il Proxy Pattern consente di aggiungere comportamenti o logiche aggiuntive (come logging, caching o gestione delle transazioni) senza modificare l’oggetto originale.
  4. Miglioramento delle Performance: Può migliorare le performance evitando il caricamento di oggetti pesanti fino a quando non sono necessari, come nel caso di oggetti remoti o con processi di inizializzazione complessi.
  5. Separazione della Logica di Controllo: Mantiene la logica di controllo separata dall’oggetto reale, migliorando la manutenibilità e la chiarezza del codice, poiché il comportamento di accesso può essere modificato senza cambiare l’oggetto originale.

Caso d’uso

Supponiamo di avere un sistema che gestisce immagini ad alta risoluzione, ma vogliamo caricare l’immagine solo quando è effettivamente richiesta, evitando costose operazioni di caricamento all’avvio.

Esempio in PHP

// Interfaccia comune
interface Image {
    public function display();
}

// Classe che rappresenta l'immagine reale
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";
    }
}

// Classe Proxy che controlla l'accesso all'immagine reale
class ProxyImage implements Image {
    private $realImage;
    private $filename;

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

    public function display() {
        // Crea l'oggetto reale solo quando necessario (lazy loading)
        if ($this->realImage == null) {
            $this->realImage = new RealImage($this->filename);
        }
        $this->realImage->display();
    }
}

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

// L'immagine viene caricata solo quando richiesta
$image1->display(); // Carica l'immagine
$image1->display(); // Non ricarica l'immagine
$image2->display(); // Carica un'altra immagine

Spiegazione

  • RealImage è l’oggetto reale che rappresenta un’immagine ad alta risoluzione e simula un caricamento costoso.
  • ProxyImage è il proxy che controlla l’accesso all’oggetto reale. In questo esempio, utilizza il caricamento “lazy”, ossia carica l’immagine solo quando il metodo display() viene chiamato per la prima volta.
  • Il client interagisce sempre con l’interfaccia Image, e non ha bisogno di sapere se sta usando l’immagine reale o il proxy. Questo rende il codice più flessibile.

Conclusione

Il Proxy Pattern è utile per ottimizzare l’accesso e la gestione di oggetti costosi da creare o sensibili. È particolarmente vantaggioso in casi d’uso come il caricamento lazy, la gestione remota degli oggetti, il controllo di accesso e il caching.

TORNA ALLA GUIDA

content_copy Copiato