Magazyn T3
newsy, felietony, testy i tutoriale



Internet Maker

24/04/2008

Wzorce projektowe – proxy

Więcej artykułów autorstwa »
Napisane przez: Marcin Staniszczak
Tagi:
37-wzorce_projektowe_-_proxy.gif

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ć:

  1. Wzorce projektowe – polecenie
  2. Wzorce projektowe – stan
  3. Wzorce projektowe – obserwator


O autorze

Marcin Staniszczak





1 komentarz


  1. kostekczwk

    i gitara, dobrze napisane



Zostaw odpowiedź

Twój adres nie zostanie opublikowany. Wymagane pola są oznaczone *

*

Możesz używać tych tagów i atrybutów HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">