všetky vzory

Simple Factory Method

Skryje voľbu konkrétnej triedy do jedinej vytváracej metódy.

class Doprava {  dorucit(zasielka) { throw new Error('abstraktná metóda'); }} class Kamion extends Doprava {  dorucit(zasielka) {    // po ceste  }} class Lod extends Doprava {  dorucit(zasielka) {    // po mori  }} class Dron extends Doprava {  dorucit(zasielka) {    // vzduchom  }} // Jediné miesto v aplikácii, kde sa menujú konkrétne triedy.class DopravaFabrika {  static pre(trasa) {    if (trasa === 'cesta') return new Kamion();    if (trasa === 'more') return new Lod();    if (trasa === 'vzduch') return new Dron();    throw new Error('neznáma trasa: ' + trasa);  }} const a = DopravaFabrika.pre('cesta');const b = DopravaFabrika.pre('more');const c = DopravaFabrika.pre('vzduch'); a.dorucit(zasielka);   // klient nenapísal ani jeden new

Celý priebeh v texte (12 krokov)
  1. Doprava je abstraktná a všetky tri konkrétne triedy ju dedia. Klient bude poznať len ju — kamión, loď ani dron nenapíše ani raz.
  2. Fabrika je jediné miesto, kde tie tri mená vôbec zaznejú. Nie je to hierarchia tried, je to jedna metóda s rozhodovaním vnútri.
  3. Klient si vypýta dopravu pre trasu "cesta". Posiela parameter, nie názov triedy.
  4. Fabrika sa rozhodla a vzniká Kamion.
  5. Von ide ako Doprava. Klient si ho odloží a s konkrétnym typom nemá čo do činenia.
  6. Druhá žiadosť, tá istá metóda a tá istá dráha — len parameter je "more".
  7. A z tej istej komory vyjde iný typ: Lod. Iný tvar, iná trieda.
  8. Klient ju prevezme presne tak isto ako kamión.
  9. Tretia žiadosť s parametrom "vzduch".
  10. Tretí typ z tej istej metódy: Dron.
  11. Aj ten putuje klientovi ako Doprava.
  12. Tri rôzne triedy vyšli z jednej metódy a po jednej dráhe. Klient nenapísal ani jeden new a o kamióne sa nikdy nedozvedel — celé rozhodovanie ostalo na jednom mieste. Že je to jedno miesto, je zároveň najväčšia slabina vzoru: každý nový typ znamená zásah práve doň.

Kedy použiť

  • Voľba konkrétnej triedy sa opakuje na viacerých miestach. Fabrika ju zoberie na seba a zvyšok aplikácie prestane menovať triedy, ktoré ho nezaujímajú.
  • Vytvorenie objektu je zložitejšie než jedno new. Keď treba doplniť závislosti, prečítať nastavenie alebo zvoliť podľa vstupu, patrí to na jedno miesto.
  • Klient má poznať len spoločné rozhranie. Dostane Dopravu a je mu jedno, či je to kamión alebo dron — pokiaľ vie doručiť.
  • Pribúdanie variantov má byť lacné. Nová trieda znamená jeden riadok vo fabrike a nič inde; bez nej by sa hľadalo po celej aplikácii.
  • Vstup rozhoduje až za behu. Keď typ určuje parameter, konfigurácia alebo odpoveď servera, statické new sa nedá napísať vôbec.

Pasce

  • Zamieňa sa s Factory Method z GoF. Tam rozhoduje podtrieda — každý creator vytvára svoj produkt a rozhodnutie je v hierarchii. Tu rozhoduje jedna metóda podľa parametra a žiadna hierarchia fabrík neexistuje. Sú to dva rôzne vzory s podobným menom.
  • Fabrika porušuje otvorenosť voči rozšíreniu. Každý nový typ znamená zásah do tej istej metódy — vzor sústredí zmenu na jedno miesto, ale nezbaví vás jej.
  • Podmienka vo fabrike rastie, kým sa nestane neprehľadnou. Desať typov je desať vetiev v jednej metóde a nikto ju už nechce otvárať.
  • Neznámy vstup musí niečo urobiť. Fabrika, ktorá pri neznámom kľúči ticho vráti nič, presunie chybu ďaleko od miesta, kde vznikla.
  • Vzor nie je vzorom GoF a v knihe ho nenájdete. Je to bežný a užitočný zvyk, no dohadovať sa o ňom ako o kanonickom vzore je zbytočné.
  • Fabrika sa stane skladiskom. Keď do nej pribudne aj načítanie nastavení, prihlasovanie a cache, prestane byť miestom, kde sa volí trieda, a stane sa miestom, kde je všetko.
  • Klient si typ aj tak vypýta menom. Keď fabrike posiela reťazec „kamion", názov triedy z aplikácie nezmizol — len sa premenil na text, ktorý nikto nekontroluje.