všetky vzory

Null Object

Dodá neutrálneho zástupcu namiesto prázdnej hodnoty, takže volanie nepadne.

class Zlava {  uplatni(suma) { throw new Error('abstraktná metóda'); }} class ZimnaZlava extends Zlava {  uplatni(suma) {    return suma * 0.8;  }} // Neutrálny zástupca: rozhranie spĺňa, ale nerobí nič.class ZiadnaZlava extends Zlava {  uplatni(suma) {    return suma;  }} class Kosik {  constructor(zlava) {    this.zlava = zlava;  }   cena(suma) {    // Žiadna kontrola na prázdnu hodnotu — nie je čo kontrolovať.    return this.zlava.uplatni(suma);  }} const sZlavou = new Kosik(new ZimnaZlava());const bezZlavy = new Kosik(new ZiadnaZlava()); sZlavou.cena(100);    // 80bezZlavy.cena(100);   // 100

Celý priebeh v texte (9 krokov)
  1. Zlava je abstraktná a vie jediné: zmeniť sumu. Obe implementácie ju dedia — aj tá, ktorá nerobí nič.
  2. Prvý košík má zimnú zľavu. Drží si ju ako ktorúkoľvek inú.
  3. Košík počíta cenu a zľavu použije. Nepýta sa, či nejakú má — volá ju rovno.
  4. Naspäť príde zmenená suma. Sto eur sa zmenilo na osemdesiat.
  5. Druhý zákazník nemá na zľavu nárok. Bez vzoru by tu bola prázdna hodnota — a košík by sa musel pred každým použitím pýtať, či vôbec nejakú zľavu má.
  6. So vzorom dostane ZiadnaZlava. Nie je to prázdno — je to plnohodnotný objekt, ktorý dedí to isté rozhranie ako zimná zľava.
  7. Košík počíta cenu presne tak isto ako predtým. Ani jedna podmienka navyše, ani jeden riadok rozdiel.
  8. A naspäť príde suma nezmenená. Volanie prebehlo, nič nespadlo a nič sa nestalo — presne to znamená „neutrálny".
  9. Prázdna hodnota by si vynútila kontrolu na každom mieste, kde sa zľava volá. Neutrálny objekt ju nahradí raz — a cena je v tom, že keď spolupracovník chýba omylom, vzor to zakryje rovnako ticho, ako keby to bol zámer.

Kedy použiť

  • Kontrola na prázdnu hodnotu sa opakuje pred každým použitím. Neutrálny objekt ju odstráni na jednom mieste namiesto toho, aby sa písala na dvadsiatich.
  • „Nič" má rozumné neutrálne správanie. Nulová zľava, prázdny zoznam, záznamník, ktorý nikam nepíše — všade existuje odpoveď, ktorá nič nepokazí.
  • Volajúci nemá riešiť výnimku z pravidla. Dostane objekt ako každý iný a zaobchádza s ním rovnako, či už niečo robí alebo nie.
  • Neprítomnosť je bežný, nie výnimočný stav. Keď väčšina objednávok nemá zľavu, nemá zmysel robiť z toho zvláštny prípad.

Pasce

  • Ticho zakryje chybu. Keď spolupracovník chýba omylom, neutrálny objekt sa zachová rovnako ako pri zámernom „nič" — a program beží ďalej, akoby bolo všetko v poriadku.
  • Neutrálne správanie nie je vždy zrejmé. Pri zľave je to nula, pri záznamníku ticho — ale pri metóde, ktorá má niečo vrátiť, sa treba rozhodnúť a to rozhodnutie nemusí byť správne pre všetkých.
  • Rozmnoží sa. Každé rozhranie potrebuje vlastnú neutrálnu implementáciu a väčšina z nich má samé prázdne metódy.
  • Nedá sa rozlíšiť od skutočného. Kto potrebuje vedieť, či zľava naozaj existuje, sa musí pýtať na typ — a to je presne tá kontrola, ktorú mal vzor odstrániť.
  • Zamieňa sa s Null Safety v jazyku. Ochrana pred prázdnou hodnotou je vlastnosť jazyka a hovorí „tu nič nie je"; neutrálny objekt hovorí „tu je niečo, čo nič nerobí". To druhé je rozhodnutie o správaní, nie o type.
  • Neutrálny objekt so stavom prestane byť neutrálny. Akonáhle si niečo pamätá alebo počíta, je to obyčajná implementácia s mätúcim menom.