všetky vzory

Dependency Injection

Podá objektu jeho závislosti zvonku namiesto toho, aby si ich zháňal sám.

class Logger {  write(message) { throw new Error('abstraktná metóda'); }} class FakeLogger extends Logger {  written = [];  write(message) { this.written.push(message); }} class FileLogger extends Logger {  write(message) { this.file.append(message); }} // What the service uses comes from outside — it never builds it itself.class Service {  constructor(logger) {    this.logger = logger;  }  receive(order) {    this.logger.write('received ' + order.id);  }} // Test environment: a fake logger, nothing is really written.const inTest = new Service(new FakeLogger());inTest.receive(order); // Production: the same service code, a real write.const inProduction = new Service(new FileLogger());inProduction.receive(order);

Celý priebeh v texte (11 krokov)
  1. Logger je abstraktný a stojí mimo oboch prostredí — je spoločný. Hovorí len to, že sa doň dá zapísať správa, nič o tom, kam. Obe implementácie ho dedia a Service nebude poznať ani jednu z nich.
  2. Service má komoru na závislosť, ale sama si do nej nič nevyrobí. Kým jej ju niekto nepodá, je prázdna — a to je celý rozdiel oproti tomu, ako sa to píše bez vzoru.
  3. Prvé prostredie: test. Všimni si, že falošný záznamník je nakreslený vnútri neho — nikde inde neexistuje. Testy nechcú zapisovať naozaj, tak si ho testovacie prostredie vyrobí u seba.
  4. A teraz to podstatné: hotový objekt podá Service. Service oň nežiadala, nič nevolala — dostala ho. Po tejto dráhe nikdy neletí volanie, len objekt.
  5. Service prijme objednávku a zapíše o nej riadok. Volá metódu na Loggeri — na abstrakcii. Do prostredia sa neobracia, o žiadnom nevie; volá objekt, ktorý má v komore.
  6. A vykonal sa toto: falošný záznamník, ten z testovacieho prostredia. Správa skončila v pamäti, test si ju vie skontrolovať a nič sa nezapísalo naozaj.
  7. Druhé prostredie: ostrá prevádzka. Tá má vnútri seba súborový záznamník a vyrobí si ten. Rovnaký tvar, lebo je to ten istý typ — iná farba, lebo je to iná implementácia.
  8. Podá ho do tej istej komory. Service je stále tá istá trieda — len tentoraz beží v druhom prostredí.
  9. Service prijme objednávku a zapíše o nej riadok — ten istý riadok kódu, to isté volanie na tú istú abstrakciu ako pred chvíľou.
  10. Ale vykonalo sa niečo iné: súborový záznamník z ostrej prevádzky. Tentoraz sa zapísalo naozaj. Volanie bolo rovnaké, prostredie iné.
  11. A to je celý vzor: ten istý kód triedy Service bežal v dvoch prostrediach a nezmenilo sa v ňom ani písmeno. Rozhodnutie, s čím pobeží, nikdy nebolo v ňom — každé prostredie si ho urobilo samo, u seba.

Kedy použiť

  • V teste falošný záznamník, v prevádzke skutočný — a trieda o tom rozdiele nevie.
  • Keď si implementáciu volí každá trieda sama, zmena znamená obísť celú aplikáciu.
  • Trieda má robiť svoju prácu, nie zháňať spolupracovníkov.
  • Spojenie do databázy ani pool nemusí vlastniť ten, kto ich používa.
  • V hlavičke konštruktora sú závislosti vymenované; poschovávané v tele metód nie.

Pasce

  • Pri Service Locatore si objekt závislosť ťahá z registra sám — stále ju zháňa, len o poschodie nižšie.
  • Konštruktor s ôsmimi parametrami vzor neopraví, len prestane skrývať. Keď to zabolí, je to nález.
  • Keď klient volá metódy, ktoré má len jedna implementácia, väzba nezmizla — presunula sa do tela.
  • Kód sa preloží aj bez podanej implementácie. Spadne až za behu.
  • Keď A potrebuje B a B potrebuje A, nemá sa kde začať. Chyba je v návrhu, nie v zostavovaní.
  • Všetky rozhodnutia o implementáciách sú na jednom mieste — a to miesto rastie s aplikáciou.