Úvod do tvorivých vzorov návrhu

1. Úvod

V softvérovom inžinierstve návrhový vzor popisuje zavedené riešenie najčastejšie sa vyskytujúcich problémov v softvérovom dizajne. Predstavuje najlepšie postupy vyvinuté počas dlhého obdobia prostredníctvom pokusov a omylov od skúsených vývojárov softvéru.

Dizajnové vzory si získali obľubu po vydaní knihy Dizajnové vzory: Prvky opakovane použiteľného objektovo orientovaného softvéru v roku 1994, ktorú vydali Erich Gamma, John Vlissides, Ralph Johnson a Richard Helm (tiež známy ako Gang štyroch alebo GoF).

V tomto článku sa budeme zaoberať tvorivými návrhovými vzormi a ich typmi. Taktiež sa pozrieme na niektoré ukážky kódu a prediskutujeme situácie, keď sa tieto vzory hodia k nášmu dizajnu.

2. Tvorivé návrhové vzory

Tvorivé návrhové vzory sa zaoberajú spôsobom, akým sú objekty vytvárané. Znižujú zložitosť a nestabilitu vytváraním objektov kontrolovaným spôsobom.

The Nový operátor sa často považuje za škodlivého, pretože rozptyľuje objekty po celej aplikácii. Postupom času môže byť náročné zmeniť implementáciu, pretože triedy sú úzko spojené.

Kreatívne vzory návrhu tento problém riešia úplným odpojením klienta od skutočného procesu inicializácie.

V tomto článku sa budeme zaoberať štyrmi typmi tvorivého návrhového vzoru:

  1. Singleton - zaisťuje, že v celej aplikácii existuje najviac iba jedna inštancia objektu
  2. Továrna metóda - vytvára objekty niekoľkých príbuzných tried bez určenia presného objektu, ktorý sa má vytvoriť
  3. Abstract Factory - Vytvára rodiny súvisiacich závislých objektov
  4. StaviteľKonštruuje zložité objekty pomocou postupného prístupu

Poďme si teraz podrobne rozobrať každý z týchto vzorov.

3. Dizajnový vzor Singleton

Cieľom Singleton Design Pattern je udržiavať kontrolu pri inicializácii objektov konkrétnej triedy pomocou zabezpečenie toho, že v rámci Java Virtual Machine existuje iba jedna inštancia objektu.

Trieda Singleton tiež poskytuje jeden jedinečný globálny prístupový bod k objektu, takže každé nasledujúce volanie prístupového bodu vráti iba tento konkrétny objekt.

3.1. Singletonov vzor

Aj keď GoF zaviedol Singletonov vzor, ​​je známe, že pôvodná implementácia je vo viacvláknových scenároch problematická.

Takže tu sa budeme riadiť optimálnejším prístupom, ktorý využíva statickú vnútornú triedu:

public class Singleton {private Singleton () {} private static class SingletonHolder {public static final Singleton instance = new Singleton (); } verejný statický Singleton getInstance () {návrat SingletonHolder.instance; }}

Tu sme vytvorili a statický vnútorná trieda, ktorá drží inštanciu Singleton trieda. Inštanciu vytvorí, iba keď niekto zavolá na getInstance () metóda a nie pri načítaní vonkajšej triedy.

Toto je široko používaný prístup pre triedu Singleton, pretože nevyžaduje synchronizáciu, je bezpečný z hľadiska vlákien, vynucuje lenivú inicializáciu a má porovnateľne menší výkon.

Upozorňujeme tiež, že konštruktér má súkromné modifikátor prístupu. Toto je požiadavka na vytvorenie produktu Singleton, pretože a verejné konštruktor by znamenal, že by k nemu mal ktokoľvek prístup a mohol začať vytvárať nové inštancie.

Pamätajte, že nejde o pôvodnú implementáciu GoF. Pôvodnú verziu nájdete v tomto prepojenom článku Baeldung o Singletons v Jave.

3.2. Kedy použiť návrhový vzor Singleton

  • Pre zdroje, ktorých vytvorenie je nákladné (napríklad objekty pripojenia k databáze)
  • Je dobrým zvykom ponechať všetky protokolovače ako Singletons, čo zvyšuje výkon
  • Triedy, ktoré poskytujú prístup k konfiguračným nastaveniam aplikácie
  • Triedy, ktoré obsahujú prostriedky, ku ktorým sa pristupuje v zdieľanom režime

4. Návrhový vzor továrenskej metódy

Factory Design Pattern alebo Factory Method Design Pattern je jedným z najpoužívanejších návrhových vzorov v Jave.

Podľa GoF tento vzor „Definuje rozhranie na vytvorenie objektu, ale podtriedy nech sa rozhodnú, ktorú triedu majú vytvoriť. Metóda Factory umožňuje triede odložiť inštanciu do podtried “.

Tento vzor deleguje zodpovednosť za inicializáciu triedy z klienta na konkrétnu továrenskú triedu vytvorením typu virtuálneho konštruktora.

Aby sme to dosiahli, spoliehame sa na továreň, ktorá nám poskytuje objekty a skrýva skutočné podrobnosti implementácie. K vytvoreným objektom sa pristupuje pomocou spoločného rozhrania.

4.1. Príklad návrhu továrenskej metódy

V tomto príklade vytvoríme a Polygón rozhranie, ktoré bude implementované niekoľkými konkrétnymi triedami. A PolygonFactory sa použije na načítanie objektov z tejto rodiny:

Najprv vytvorme Polygón rozhranie:

verejné rozhranie Polygon {String getType (); }

Ďalej vytvoríme niekoľko implementácií ako Námestie, Trojuholník, atď., ktoré implementujú toto rozhranie a vrátia objekt z Polygón typu.

Teraz môžeme vytvoriť továreň, ktorá vezme počet strán ako argument a vráti príslušnú implementáciu tohto rozhrania:

public class PolygonFactory {public Polygon getPolygon (int numberOfSides) {if (numberOfSides == 3) {return new Triangle (); } if (numberOfSides == 4) {return new Square (); } if (numberOfSides == 5) {vrátiť nový Pentagon (); } if (numberOfSides == 7) {return new Heptagon (); } else if (numberOfSides == 8) {return new Octagon (); } return null; }}

Všimnite si, ako sa klient môže spoľahnúť na to, že táto továreň nám poskytne príslušné prostriedky Polygón, bez nutnosti priamej inicializácie objektu.

4.2. Kedy použiť návrhový vzor výrobnej metódy

  • Keď sa očakáva, že sa implementácia rozhrania alebo abstraktnej triedy bude často meniť
  • Keď súčasná implementácia nemôže pohodlne vyhovieť novým zmenám
  • Keď je proces inicializácie pomerne jednoduchý a konštruktor vyžaduje iba niekoľko parametrov

5. Abstraktný návrhový vzor továrne

V predchádzajúcej časti sme videli, ako je možné použiť návrhový vzor Factory Method na vytvorenie objektov súvisiacich s jednou rodinou.

Naopak, abstraktný návrhový vzor továrne sa používa na vytváranie skupín príbuzných alebo závislých objektov. Niekedy sa mu hovorí aj továreň na továrne.

Podrobné vysvetlenie nájdete v našom výučbovom programe Abstract Factory.

6. Návrhový vzor staviteľa

Dizajnový vzor Builder je ďalší tvorivý vzor navrhnutý na riešenie stavby pomerne zložitých objektov.

Keď sa zložitosť vytvárania objektu zvýši, vzor Builder môže oddeliť proces inštancie použitím iného objektu (staviteľa) na vytvorenie objektu.

Tento tvorca potom možno použiť na vytvorenie mnohých ďalších podobných reprezentácií pomocou jednoduchého postupného postupu.

6.1. Príklad staviteľského vzoru

Pôvodný návrhový vzor Builder, ktorý predstavila spoločnosť GoF, sa zameriava na abstrakciu a je veľmi dobrý pri práci so zložitými objektmi. Dizajn je však trochu komplikovaný.

Joshua Bloch vo svojej knihe Effective Java predstavil vylepšenú verziu modelu staviteľa, ktorá je čistá, dobre čitateľná (pretože využíva plynulý dizajn) a je ľahko použiteľná z pohľadu klienta. V tomto príklade si rozoberieme túto verziu.

Tento príklad má iba jednu triedu, Bankový účet ktorý obsahuje staviteľ ako a statický vnútorná trieda:

public class BankAccount {private String name; private String accountNumber; súkromný reťazcový e-mail; súkromný boolovský spravodaj; // konštruktory / getre verejná statická trieda BankAccountBuilder {// kód staviteľa}} 

Upozorňujeme, že všetky modifikátory prístupu k poliam sú deklarované súkromné pretože nechceme, aby k nim mali vonkajšie objekty priamy prístup.

Konštruktér je tiež súkromné aby k nej mal prístup iba Builder priradený k tejto triede. Všetky vlastnosti nastavené v konštruktore sa extrahujú z objektu staviteľa, ktorý dodávame ako argument.

Definovali sme BankAccountBuilder v statický vnútorná trieda:

public static class BankAccountBuilder {private String name; private String accountNumber; súkromný reťazcový e-mail; súkromný boolovský spravodaj; public BankAccountBuilder (názov reťazca, reťazec číslo účtu) {this.name = meno; this.accountNumber = accountNumber; } verejný BankAccountBuilder withEmail (reťazcový e-mail) {this.email = e-mail; vráťte to; } public BankAccountBuilder wantNewsletter (boolean newsletter) {this.newsletter = newsletter; vráťte to; } public BankAccount build () {vrátiť nový BankAccount (tento); }} 

Všimnite si, že sme deklarovali rovnakú množinu polí, ktoré obsahuje vonkajšia trieda. Akékoľvek povinné polia sú povinné ako argumenty pre konštruktor vnútornej triedy, zatiaľ čo zvyšné voliteľné polia je možné určiť pomocou metód setter.

Táto implementácia podporuje aj prístup plynulého návrhu tým, že metódy setteru vrátia objekt staviteľa.

Nakoniec metóda build zavolá súkromného konštruktora vonkajšej triedy a odovzdá sa ako argument. Vrátený Bankový účet bude inštancovaný s parametrami nastavenými v BankAccountBuilder.

Pozrime sa na krátky príklad modelu staviteľa v akcii:

BankAccount newAccount = nový BankAccount .BankAccountBuilder ("Jon", "22738022275") .withEmail ("[chránený e-mailom]") .wantNewsletter (true) .build ();

6.2. Kedy použiť Builder Pattern

  1. Keď je proces vytvárania objektu nesmierne zložitý, s množstvom povinných a voliteľných parametrov
  2. Keď zvýšenie počtu parametrov konštruktora vedie k veľkému zoznamu konštruktorov
  3. Keď klient očakáva rôzne reprezentácie pre objekt, ktorý je zostrojený

7. Záver

V tomto článku sme sa dozvedeli o kreačných návrhových vzoroch v Jave. Diskutovali sme tiež o ich štyroch rôznych typoch, t. J. Singleton, Factory Method, Abstract Factory a Builder Pattern, o ich výhodách, príkladoch a o tom, kedy by sme ich mali použiť.

Kompletné útržky kódu sú ako vždy k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found