Dziś poznasz jeden z prostszych wzorców projektowych (strukturalnych). Wzorzec ten nosi nazwę proxy, co jest czasami tłumaczone jako pełnomocnik (takie tłumaczenie można znaleźć między innymi w kultowej już pozycji autorstwa „bandy czworga” – Ericha Gamma, Richarda Helema, Ralpha Johnsona oraz Johna Vlissidesa – Wzorce projektowe, wydanej przez WNT)
Wzorzec ten ma na celu zbudowanie klasy będącej odpowiednikiem innej klasy, pozwalając jednocześnie na zarządzanie dostępem do niej:
- gdy chcesz wykonywać pewne zdalne obiekty(remote proxy – pełnomocnik zdalny),
- gdy z pewnych względów nie chcesz tworzyć obiektu danej klasy aż do chwili wywołania jednej z jego metod, np. gdy z góry wiesz, że utworzenie takiego obiektu jest bardzo czasochłonne bądź zasobochłonne (virtual proxy – pełnomocnik wirtualny),
- gdy chcesz kontrolować dostęp do pewnego obiektu twojego systemu (protection proxy – pełnomocnik ochraniający),
- gdy poza akcją wykonywaną przez obiekt danej klasy musisz wykonać także dodatkowe akcje powiązane z jego metodą bądź metodami (smart proxy – sprytny pełnomocnik).
Nie są to wszystkie możliwe użycia wzorca proxy, lecz te najbardziej typowe. Nic jednak nie stoi na przeszkodzie, aby wykorzystać go w innym celu.
Jak działa proxy? Zawsze w sposób analogiczny. Obudujmy więc, korzystając z tego wzorca, przykładową klasę Klient. Klasa ta implementuje interfejs Uzytkownik:
1 2 3 4 5 6 7 8 |
interface Uzytkownik { public function getImie(); public function setImie($strImie); public function getNazwisko(); public function setNazwisko($strNazwisko); public function zapisz(); public function usun(); } |
1 2 3 4 5 6 7 8 |
public interface Uzytkownik { public String getImie(); public void setImie(String imie); public String getNazwisko(); public void setNazwisko(String nazwisko); public void zapisz(); public void usun(); } |
Nasza klasa Klient jest równie prosta (jak
zwykle ciała funkcji nie robią nic pożytecznego
- przykłady te mają jedynie zaprezentować
w możliwie łatwy i przejrzysty sposób samą ideę
działania wzorca):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Klient implements Uzytkownik { private $strImie; private $strNazwisko; public function getImie() { return $this->strImie; } public function setImie($strImie) { $this->strImie = $strImie; } public function getNazwisko() { return $this->strNazwisko; } public function setNazwisko($strNazwisko) { $this->strNazwisko = $strNazwisko; } public function zapisz() { //zapisywanie danych użytkownika } public function usun() { //usuwanie użytkownika } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class Klient implements Uzytkownik { private String imie; private String nazwisko; public String getImie() { return imie; } public void setImie(String imie) { this.imie = imie; } public String getNazwisko() { return nazwisko; } public void setNazwisko(String nazwisko) { this.nazwisko = nazwisko; } public void zapisz() { //zapisywanie danych użytkownika } public void usun() { //usuwanie użytkownika } } |
Nasza klasa Proxy także dziedziczy po interfejsie
Użytkwonik, udając tym samym klasę, którą
obudowuje:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class Proxy implements Uzytkownik { private $objKlient; public function __construct() { $this->objKlient = new Klient(); //inne działania proxy w dane metodzie } public function getImie() { return $this->objKlient->getImie(); //inne działania proxy w dane metodzie } public function setImie($strImie) { $this->objKlient->setImie($strImie); //inne działania proxy w dane metodzie } public function getNazwisko() { return $this->objKlient->getNazwisko(); //inne działania proxy w dane metodzie } public function setNazwisko($strNazwisko) { $this->objKlient->setNazwisko($strNazwisko); //inne działania proxy w dane metodzie } public function zapisz() { $this->objKlient->zapisz(); //inne działania proxy w dane metodzie } public function usun() { $this->objKlient->usun(); //inne działania proxy w dane metodzie } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class Proxy implements Uzytkownik { private Klient klient; public Proxy() { klient = new Klient(); } public String getImie() { return klient.getImie(); //inne działania proxy w dane metodzie } public void setImie(String imie) { klient.setImie(imie); //inne działania proxy w dane metodzie } public String getNazwisko() { return klient.getNazwisko(); //inne działania proxy w dane metodzie } public void setNazwisko(String nazwisko) { klient.setNazwisko(nazwisko); //inne działania proxy w dane metodzie } public void zapisz() { klient.zapisz(); //inne działania proxy w dane metodzie } public void usun() { klient.usun(); //inne działania proxy w dane metodzie } } |
Użycie wzorca proxy sprowadza się do użycia
naszej nowej klasy Proxy w miejscu klasy Klient.
Jako że obie mają ten sam interfejs, nie sprawia to
żadnego problemu:
1 2 3 4 |
$objUzytkownik = new Proxy(); $objUzytkownik->setImie(\'Jan\'); $objUzytkownik->setNazwisko(\'Kowalski\'); $objUzytkownik->zapisz(); |
1 2 3 4 5 6 7 8 9 |
public class Test { public static void main(String[] args) { Uzytkownik uzytkownik = new Proxy(); uzytkownik.setImie(\"Jan\"); uzytkownik.setNazwisko(\"Kowalski\"); uzytkownik.zapisz(); } } |
Podsumowanie
Wzorzec ten jest prawdopodobnie najprostszym
z poznanych przez ciebie do tej pory.
Możliwe, że już od dawna z niego korzystasz, nie
wiedząc nawet, że jest to jeden ze wzorców i jaką
nosi nazwę. Jeśli tak, warto jego nazwę zapamiętać.
Pozwoli to na wygodną komunikację z innymi
programistami, operującymi terminologią wzorców
projektowych.
Może Cię zainteresować:




i gitara, dobrze napisane