Zastosowanie
Pełnomocnik
(ang. Proxy
) (wzorzec strukturalny) tworzy obiekt, którego zadaniem jest reprezentowanie (pełnienie pełnomocnictwa) innego obiektu. Na podstawie stanu systemu i spełnienia warunków obiekt klasy pełnomocnika Proxy
, decyduje o utworzeniu bądź nie instancji klasy obiektu docelowego i wywołaniu na nim odpowiednich metod. Takie podejście zapewnia kontrolowane tworzenie kosztownych obiektów oraz kontrolę dostępu. W przypadku nie spełnienia warunków (np.: błędne hasło) pomijany jest proces tworzenia kosztownego obiektu i wywołania na nim metody, która nie może zostać wykonana zgodnie z oczekiwaniami systemu czy użytkownika. Wzorzec ten umożliwia realizowanie dodatkowych zadań w ramach emulowanego obiektu.
Ograniczenia
Wykorzystując wzorzec Pełnomocnik
, należy mieć na uwadze, że poza oczywistymi korzyściami wynikającymi z późnego inicjalizowania i dodatkowego sprawdzania warunków można odnotować opóźnienie w odpowiedzi czy wykonaniu zadania. Wzorzec ten jest podobny w strukturze do Dekoratora
, jednakże Pełnomocnik
zarządza cyklem życia obiektów emulowanych, natomiast struktura obiektu klasy implementującego wzorzec Dekorator
jest zarządzana przez użytkownika. Ponadto ze względu na opakowanie inicjalizowania obiektu i wywołania jego metod może przypominać wariacje wzorców Fasada
oraz Adapter
. Ze względu na podobieństwa do innych wzorców decyzja o wyborze wzorca Pełnomocnik
może nie być trywialna.
Użycie
Pełnomocnik
jest wykorzystywany przede wszystkim w sytuacjach, gdzie należy zapewnić kontrolę dostępu do obiektu (np. proces autoryzacji). Znajduje również zastosowanie w procesie tworzenia kosztownych obiektów (np. dostęp do bazy danych) oraz emulacji zdalnego obiektu (np. przesyłanie danych).
Implementacja
Klasa pełnomocnika Proxy
oraz klasa RealSubject
, której obiekt udziela pełnomocnictwa implementują interfejs Subject
. Klasa Proxy
zawiera prywatne pole typu Subject
, które w zależności od ustalonych warunków jest inicjalizowane instancją klasy RealSubject
. Klasa Proxy
nadpisuje metody interfejsu w taki sposób, że wywołują one odpowiadające im metody obiektu klasy RealSubject
.
Poniższy listing przedstawia implementacje wzorca Pełnomocnik
dla klasy RealSubject
w oparciu o proces autoryzacji.
Klient inicjalizuje obiekt typu Subject
instancją klasy Proxy
, a następnie wywołuje na nim żądane metody.
Przykład
Aplikacja Tasker
umożliwia przechowywanie i zarządzanie listą zadań w trybie online i offline oraz współdzielenia zasobów w obrębie zespołu. Każdy użytkownik zespołu może przeglądać listę zadań, jednak tylko autoryzowani użytkownicy mogą dodawać lub usuwać zadania. Gdy system nie ma połączenia z internetem wówczas ładowane są dane z pamięci podręcznej aplikacji. W celu optymalizacji zużycia kosztownych zasobów (tworzenie obiektów) oraz pakietu danych, aplikacja wykorzystuje wzorzec Pełnomocnik
do sprawdzenia stanu połączenia internetowego oraz autoryzacji użytkownika, co przedstawia poniższy listing.
Sposób wykorzystania Pełnomocnika
dla TaskManager
może przebiegać następująco.
Biblioteki
Ze względu na prostotę wzorca opartą o implementacje wspólnego interfejsu, biblioteki implementujące wzorzec Pełnomocnik
nie mają sensu. Przykładem realizacji wzorca jest klasa Proxy
wraz z InvocationHandler
z pakietu java.lang.reflect
.