Wzorce projektowe, cz. 12 Proxy
Pełnomocnik jest wzorcem projektowym, którego celem jest utworzenie obiektu zastępującego inny obiekt. Stosowany jest on w celu kontrolowanego tworzenia na żądanie kosztownych obiektów oraz kontroli dostępu do nich.

Diagram klas wzorca Proxy
Interfejs Subcject definiuje pewną metodę. Klasy Proxy i RealSubject realizują powyższy interfejs na dwa różne sposoby. W klasie Proxy zostaje wywołana metoda doSmething() obiektu klasy RealSubject. Przed wywołaniem tej metody można oczywiście wykonać inne operacje. Obrazuje to poniższy listing.
Przykładowa implementacja
<?php interface Subject { function doSomething(); } class RealSubject implements Subject { public function doSomething() { echo 'I do something...'; } } class Proxy implements Subject { private $realSubject; public function doSomething() { if ($this->realSubject == null) { echo 'Proxy'; $this->realSubject = new RealSubject(); } $this->realSubject->doSomething(); } } $obj = new Proxy(); $obj->doSomething(); // wyswietli najpierw "Proxy", a nastepnie "I do something..." $obj->doSomething(); // wyswietl "I do something..." ?>
Przykład z życia wzięty
Zapewne zastanawiasz się jaki jest sens stosowania klasy pośredniczącej. Przeanalizujmy przykład, w którym wykorzystamy wzorzec Proxy dla biblioteki generującej obrazki w wysokiej rozdzielczości. Dodatkowo chcemy zabezpieczyć dostęp hasłem.
<?php interface HighResolutionImage{ function display(); } class Image implements HighResolutionImage{ private $options; public function __construct($options) { $this->options=$options; // generate image } public function display() { echo 'display image'; } } class ProxyImage implements HighResolutionImage{ private $options; private $passwrd; private $image = null; public function __construct($options, $password) { $this->options=$options; $this->passwrd=$password; } public function display() { if($this->passwrd=='tajne') { if($this->image==null) { $this->image=new Image($this->options); } $this->image->display(); } else { echo 'Access denied'; } } } $image = new ProxyImage(array('width' => 3800, 'height' => 2000), 'tajne'); $image2 = new ProxyImage(array('width' => 3800, 'height' => 2000), 'tajne2'); $image->display(); // wyswietli "display image" $image2->display(); // wyswietli "Access denied" ?>
Dzięki wykorzystaniu ProxyImage obrazek zostanie wygenerowany tylko w przypadku podania prawidłowego hasła oraz w sytuacji, gdy naprawdę istnieje potrzeba jego wyświetlenia.
Zastosowanie
Wzorzec Proxy możemy wykorzystać w sytuacji, gdy koszt utworzenia obiektu jest wysoki, a wykorzystanie danego obiektu uzależnione jest od spełnienia pewnych warunków.