Design patterns: Proxy

data: · 3 min
autore: Mauto
serie: Design Patterns/ parte 13/24

I pattern classici della Gang of Four, uno per puntata, con esempi pratici in PHP.

  1. Design Patterns
  2. Design patterns: Singleton
  3. Design patterns: Factory Method
  4. Design patterns: Abstract Factory
  5. Design patterns: Builder
  6. Design patterns: Prototype
  7. Design patterns: Adapter
  8. Design patterns: Bridge, cos’è e come usarlo (esempio PHP)
  9. Design patterns: Composite
  10. Design patterns: Decorator
  11. Design patterns: Facade, cos’è e come usarlo (esempio PHP)
  12. Design patterns: Flyweight
  13. Design patterns: Proxy
  14. Design patterns: Chain of Responsibility, cos’è (esempio PHP)
  15. Design patterns: Command
  16. Design patterns: Interpreter
  17. Design patterns: Iterator
  18. Design patterns: Mediator
  19. Design patterns: Memento
  20. Design patterns: Observer
  21. Design patterns: State, cos’è e come usarlo (esempio PHP)
  22. Design patterns: Strategy
  23. Design patterns: Template Method
  24. Design patterns: Visitor
tutta la guida >

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 "Caricamento immagine dal disco: {$this->filename}\n";
    }

    public function display() {
        echo "Visualizzazione immagine: {$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

Copiato