všetky vzory

Proxy

Postaví pred objekt zástupcu, ktorý prístup k nemu riadi alebo odkladá.

class Obraz {  vykresli() { throw new Error('abstraktná metóda'); }} class SkutocnyObraz extends Obraz {  constructor(cesta) {    super();    // Drahé: načíta celý súbor z disku.    this.data = nacitaj(cesta);  }   vykresli() {    // vykreslí načítané dáta  }} class ObrazProxy extends Obraz {  constructor(cesta) {    super();    this.cesta = cesta;    this.skutocny = null;  }   vykresli() {    if (this.skutocny === null) {      this.skutocny = new SkutocnyObraz(this.cesta);    }    this.skutocny.vykresli();  }} const obraz = new ObrazProxy('mapa.png');obraz.vykresli();   // až teraz sa načíta z diskuobraz.vykresli();   // druhýkrát sa už nenačítava

Celý priebeh v texte (10 krokov)
  1. Obraz je abstraktný a dedia ho obaja: zástupca aj skutočný obraz. Práve preto klient nespozná, s ktorým z nich hovorí — a preto sa dá jeden nahradiť druhým.
  2. Klient drží zástupcu a myslí si, že drží obraz. Skutočný obraz zatiaľ neexistuje — komora zástupcu je prázdna a z disku sa nenačítalo nič.
  3. Klient zavolá vykresli().
  4. Zástupca zistí, že skutočný obraz ešte nemá — a až teraz ho vytvorí. Načítanie z disku sa odložilo presne na chvíľu, keď je naozaj potrebné.
  5. A až potom pošle volanie ďalej.
  6. Klient zavolá vykresli() druhýkrát. To isté volanie, ten istý objekt v ruke.
  7. Tentoraz zástupca nič nevytvára — skutočný obraz už má, tak volanie iba posunie ďalej. Cena za načítanie sa zaplatila raz.
  8. A teraz to, čo zástupcu odlišuje od všetkého ostatného. Klient zavolá tretíkrát — lenže tentoraz nemá právo.
  9. Volanie sa zastaví u zástupcu a ďalej nejde. Skutočný obraz sa o ňom nikdy nedozvie — zástupca prístup riadi, nie iba sprostredkúva.
  10. Klient celý čas volal to isté a ani raz sa nedozvedel, či hovorí so zástupcom alebo so skutočným obrazom. A tu je rozdiel oproti dekorátoru: zástupca nič nepridal, iba rozhodol, čo prejde ďalej a kedy.

Kedy použiť

  • Skutočný objekt je drahý a možno ho nikto nepoužije. Zástupca ho vytvorí až pri prvom skutočnom použití a pri ostatných sa nestane nič.
  • Prístup treba strážiť. Zástupca skontroluje právo skôr, než volanie pustí ďalej — a volajúci pritom drží to isté rozhranie ako predtým.
  • Objekt je inde a hovoriť s ním treba cez sieť. Zástupca schová celú komunikáciu za obyčajné volanie metódy.
  • Okolo volaní treba pridať evidenciu, počítanie odkazov alebo cache. Sú to veci, ktoré do skutočného objektu nepatria, ale niekto ich robiť musí.

Pasce

  • Zamieňa sa s Decoratorom. Obidva majú rovnaké rozhranie ako to, čo držia, ale dekorátor chovanie pridáva a zástupca ho riadi. Dekorátorov sa navrství viacero, zástupca býva jeden a rozhoduje, či sa volanie vôbec dostane ďalej.
  • Zamieňa sa s delegovaním. Kto deleguje, má vlastné rozhranie a pomocníka len používa. Zástupca sa za zastupovaného vydáva — musí byť navonok tým istým typom, inak by ho nemohol nahradiť.
  • Zástupca musí byť naozaj zameniteľný. Akonáhle sa správa inak než skutočný objekt — inak ohlási chybu, inak porovná identitu — prestane byť zástupcom a stane sa skrytou zmenou správania.
  • Odložené vytvorenie presunie cenu inam. Prvé volanie je zrazu pomalé a nikto nečaká, že práve ono siahne na disk či na sieť.
  • Sieťový zástupca klame o cene volania. Vyzerá ako metóda, ale je to požiadavka cez sieť — a volajúci ju pokojne zavolá v cykle tisíckrát.
  • Vrstva navyše sa dá zabudnúť. Kto si vypýta skutočný objekt priamo, obíde kontrolu prístupu aj cache — a zástupca o tom nemá ako vedieť.