Modele orientate spre obiecte în JavaScript: Factory Pattern

Organizarea codului ne va scuti de multă durere. Folosind caracteristicile programării orientate pe obiecte, putem utiliza anumite modele de proiectare pentru a obține o mai bună lizibilitate, pentru a reduce redundanța și pentru a crea abstracțiuni, dacă este necesar. Un astfel de model este modelul fabrică.

Patronul fabrică este un tip de model orientat pe obiecte care urmează metodologia DRY. După cum sugerează și numele, instanțele de obiecte sunt create prin utilizarea unei fabrici care să realizeze obiectul necesar pentru noi.

Să ne uităm la un exemplu foarte simplu de utilizare a modelului fabrică pentru a asambla un obiect alligator. Pentru a face acest lucru, trebuie mai întâi să creăm fabrici care să creeze părțile alligator pentru noi:

class TailFactory { constructor(props) { this.tailLength = props.tailLength; }};class TorsoFactory { constructor(props) { this.color = props.color; }};class HeadFactory { constructor(props) { this.snoutLenth = props.snoutLenth; }};

Acum, creăm o clasă care acționează ca un intermediar între clasele reale ale fabricilor și utilizator. Să o numim ReptilePartFactory:

class ReptilePartFactory { constructor(type, props) { if(type === "tail") return new TailFactory(props); if(type === "torso") return new TorsoFactory(props); if(type === "head") return new HeadFactory(props); }};

Să mergem mai departe și să asamblăm acum aligatorul propriu-zis și să folosim ReptilePartFactory pentru a obține piesele necesare pentru noi:

let alligator = {};let alligatorProps = { tailLength : 2.5, color: "green", snoutLenth: 1};//gets a tail from the tail factoryalligator.tail = new ReptilePartFactory("tail", alligatorProps); //gets a torso from the torso factoryalligator.torso = new ReptilePartFactory("torso", alligatorProps);//gets a head from the head factoryalligator.head = new ReptilePartFactory("head", alligatorProps);

După cum arată modelul de mai sus, se pare că am putea folosi aceeași ReptilePartFactory pentru a crea piese pentru obiecte de tip aligator. Fabricile din fundal nu ar trebui să știe niciodată despre natura obiectului final.

Așa, folosirea modelului de fabrică ne oferă anumite avantaje:

  • Crearea dinamică a obiectelor: Poate fi utilizat în cazurile în care tipul obiectului este decis la momentul execuției.
  • Abstractizare: Utilizatorul nu trebuie niciodată să acceseze cu adevărat constructorul obiectului real.
  • Reutilizabilitate/întreținere: Aceleași fabrici pot fi folosite pentru obiecte similare și ne permite să adăugăm/eliminăm cu ușurință noi clase de obiecte fără a schimba o mulțime de cod.

Acum că avem o oarecare înțelegere a modelului de fabrică, să explorăm puțin scrierea unui cod mai bun pentru modelul de fabrică.

Exemplul de mai sus folosește un „if-ladder” pentru a afla ce fabrică trebuie apelată pe baza datelor introduse de utilizator. Aceasta este o implementare simplă, intuitivă și nu foarte deschisă la modificări. Dacă mai târziu vom avea piese noi de adăugat, atunci va trebui să deranjăm ReptilePartFactory. Aceasta este o încălcare a principiilor SOLID, care stipulează că „Entitățile software (clase, module, funcții etc.) ar trebui să fie deschise pentru extindere, dar închise pentru modificare”.

Cum ar fi să stocăm clasele fabrică într-un obiect și să apelăm fabrica de piese necesară folosind ca cheie piesa pe care o dorim? Mai întâi ar trebui să înregistrăm fabricile, ar fi la fel de simplu ca:

let registeredPartFactories = {};registeredPartFactories = class TailFactory{ ...};registeredPartFactories = class TorsoFactory { ...};registeredPartFactories = class HeadFactory { ...};

Și acum, stratul abstract poate apela fabricile astfel:

class ReptilePartFactory { constructor(type, props) { return new registeredPartFactories(props); }};

Această abordare este mult mai curată și ne permite să ne extindem fabricile fără a afecta codul din ReptilePartFactory.

În concluzie

Există alte câteva modele orientate pe obiecte care cresc, de asemenea, lizibilitatea și calitatea. Așadar, înainte de a utiliza modelul factory, verificați dacă există o cerință reală pentru acesta. Dacă aveți de gând să creați tipuri similare de obiecte în mod repetat și, de asemenea, aveți nevoie de un strat pentru a crea noi instanțe folosind aceste obiecte, oferind în același timp un anumit nivel de abstractizare a logicii de creare, atunci da – modelul factory este o opțiune bună.

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.