logo

Vzor návrhu metódy Singleton

Singleton Pattern je pravdepodobne najpoužívanejší dizajnový vzor. Je to jednoduchý vzor, ​​ľahko pochopiteľný a použiteľný. Niekedy sa používa v nadmernom množstve av scenároch, kde sa to nevyžaduje. V takýchto prípadoch prevažujú nevýhody jeho používania nad výhodami, ktoré prináša. Z tohto dôvodu sa singleton vzor niekedy považuje za jeden antivzor alebo vzor singleton .

Singleton-Method-Design-Pattern



Dôležité témy pre návrhový vzor metódy Singleton

1. Čo je to vzor návrhu metódy Singleton?

Metóda Singleton alebo vzor Singleton Design je jedným z najjednoduchších dizajnových vzorov. Zabezpečuje, že trieda má iba jednu inštanciu a poskytuje k nej globálny prístupový bod.

2. Kedy použiť Singleton Method Design Pattern?

Návrhový vzor metódy Singleton použite, keď:



  • Musí existovať presne jedna inštancia triedy a musí byť prístupná klientom zo známeho prístupového bodu.
  • Keď by jediná inštancia mala byť rozšíriteľná pomocou podtried a klienti by mali byť schopní používať rozšírenú inštanciu bez úpravy
  • Triedy Singleton sa používajú na protokolovanie, objekty ovládačov, ukladanie do vyrovnávacej pamäte a oblasť vlákien, pripojenia k databáze.

3. Typy inicializácie Singleton

Trieda Singleton môže byť vytvorená dvoma spôsobmi:

  • Skorá inicializácia: Pri tejto metóde sa trieda inicializuje bez ohľadu na to, či sa má použiť alebo nie. Hlavnou výhodou tejto metódy je jej jednoduchosť. Triedu spustíte v čase načítania triedy. Jeho nevýhodou je, že trieda sa vždy inicializuje, či už sa používa alebo nie.
  • Lenivá inicializácia: Pri tejto metóde sa trieda inicializuje iba vtedy, keď je to potrebné. Môže vás to ušetriť od vytvárania inštancie triedy, keď ju nepotrebujete. Vo všeobecnosti sa lenivá inicializácia používa, keď vytvárame triedu singleton.

4. Kľúčový komponent vzoru návrhu metódy Singleton:

Key-Component-of-Singleton-Method-Design-Pattern-(1)

4.1. Statický člen:

Vzor Singleton alebo vzor Singleton využíva v rámci triedy statický člen. Tento statický člen zaisťuje, že pamäť je alokovaná iba raz, pričom zachováva jedinú inštanciu triedy Singleton.



Java
// Static member to hold the single instance private static Singleton instance;>

4.2. Súkromný konštruktér:

Vzor Singleton alebo vzor singleton obsahuje súkromný konštruktor, ktorý slúži ako barikáda proti vonkajším pokusom o vytvorenie inštancií triedy Singleton. To zaisťuje, že trieda má kontrolu nad procesom vytvárania inštancií.

Java
// Private constructor to // prevent external instantiation class Singleton {  // Making the constructor as Private  private Singleton()  {  // Initialization code here  } }>

4.3. Statická výrobná metóda:

Rozhodujúcim aspektom vzoru Singleton je prítomnosť statickej továrenskej metódy. Táto metóda funguje ako brána, ktorá poskytuje globálny prístupový bod k objektu Singleton. Keď niekto požaduje inštanciu, táto metóda buď vytvorí novú inštanciu (ak žiadna neexistuje), alebo vráti existujúcu inštanciu volajúcemu.

Java
// Static factory method for global access public static Singleton getInstance() {  // Check if an instance exists  if (instance == null) {  // If no instance exists, create one  instance = new Singleton();  }  // Return the existing instance  return instance; }>

5. Implementácia vzoru Singleton Method Design Pattern

Implementácia Singleton Design Pattern alebo Pattern Singleton je opísaná v nasledujúcom diagrame tried:

Snímka obrazovky-2023-12-07-174635

Implementácia vzoru Singleton Method Design Pattern

Implementácia vzoru singleton Design je veľmi jednoduchá a pozostáva z jedinej triedy. Aby sa zabezpečilo, že inštancia singleton je jedinečná, všetky konštruktory singleton by mali byť súkromné. Globálny prístup sa vykonáva prostredníctvom statickej metódy, ku ktorej je možné globálne pristupovať k jednej inštancii, ako je uvedené v kóde.

Java
/*package whatever //do not write package name here */ import java.io.*; class Singleton {  // static class  private static Singleton instance;  private Singleton()  {  System.out.println('Singleton is Instantiated.');  }  public static Singleton getInstance()  {  if (instance == null)  instance = new Singleton();  return instance;  }  public static void doSomething()  {  System.out.println('Somethong is Done.');  } } class GFG {  public static void main(String[] args)  {  Singleton.getInstance().doSomething();  } }>

Výkon
Singleton is Instantiated. Somethong is Done.>

Metódou getInstance skontrolujeme, či je inštancia nulová. Ak inštancia nie je nulová, znamená to, že objekt bol vytvorený skôr; inak ho vytvoríme pomocou operátora new.

6. Rôzne spôsoby implementácie vzoru návrhu metódy Singleton

Niekedy potrebujeme mať iba jednu inštanciu našej triedy, napríklad jedno DB pripojenie zdieľané viacerými objektmi, pretože vytvorenie samostatného DB pripojenia pre každý objekt môže byť nákladné. Podobne môže byť v aplikácii jeden správca konfigurácie alebo správca chýb, ktorý rieši všetky problémy namiesto vytvárania viacerých manažérov.

Klasická implementácia

veľkosti latexového textu

Pozrime sa na rôzne možnosti návrhu implementácie takejto triedy. Ak dobre ovládate statické premenné triedy a modifikátory prístupu, nemala by to byť náročná úloha.

Metóda 1 – klasická implementácia || Implementujte getInstance() ako statickú Vzor návrhu metódy Singleton

Java
// Classical Java implementation of singleton // design pattern class Singleton {  private static Singleton obj;  // private constructor to force use of  // getInstance() to create Singleton object  private Singleton() {}  public static Singleton getInstance()  {  if (obj == null)  obj = new Singleton();  return obj;  } }>

Tu sme vyhlásili getInstance() statické, aby sme ho mohli volať bez vytvárania inštancie triedy. Prvý krát getInstance() sa nazýva, že vytvorí nový singleton objekt a potom len vráti ten istý objekt.

Poznámka: Singleton obj sa nevytvorí, kým ho nepotrebujeme a nezavoláme getInstance() metóda. Toto sa nazýva lenivá inštancia. Hlavným problémom vyššie uvedenej metódy je, že nie je bezpečná pre vlákna. Zvážte nasledujúcu postupnosť vykonávania.

Táto sekvencia vykonávania vytvorí dva objekty pre singleton. Preto táto klasická implementácia nie je bezpečná pre vlákna.

Metóda 2 || Synchronizujte getInstance() na implementáciu Vzor návrhu metódy Singleton

Java
// Thread Synchronized Java implementation of // singleton design pattern class Singleton {  private static Singleton obj;  private Singleton() {}  // Only one thread can execute this at a time  public static synchronized Singleton getInstance()  {  if (obj == null)  obj = new Singleton();  return obj;  } }>

Tu pomocou synchronizácie zaistíte, že naraz môže byť spustené iba jedno vlákno getInstance() . Hlavnou nevýhodou tejto metódy je, že použitie synchronizovaného zakaždým pri vytváraní singleton objektu je drahé a môže znížiť výkon vášho programu. Ak však výkon z getInstance() nie je pre vašu aplikáciu rozhodujúca, táto metóda poskytuje čisté a jednoduché riešenie.

Metóda 3 – Eager Instanciation || Implementácia jednotónového návrhového vzoru založená na statickom inicializátore

Java
// Static initializer based Java implementation of // singleton design pattern class Singleton {  private static Singleton obj = new Singleton();  private Singleton() {}  public static Singleton getInstance() { return obj; } }>

Tu sme vytvorili inštanciu singletonu v statickom inicializátore. JVM spustí statický inicializátor, keď sa trieda načíta, a preto je zaručené, že je bezpečné pre vlákna. Túto metódu použite iba vtedy, keď je vaša trieda singleton ľahká a používa sa počas vykonávania vášho programu.

Metóda 4 – Najúčinnejšia || Použite dvojitú kontrolu zamykania na implementáciu jednoduchého vzoru návrhu

Ak si po vytvorení objektu pozorne všimnete, synchronizácia už nie je užitočná, pretože objekt obj teraz nebude mať hodnotu null a každá postupnosť operácií povedie ku konzistentným výsledkom. Takže zámok na getInstance() získame iba raz, keď je obj null. Takto zosynchronizujeme len prvú cestu, presne to, čo chceme.

Java
// Double Checked Locking based Java implementation of // singleton design pattern class Singleton {  private static volatile Singleton obj = null;  private Singleton() {}  public static Singleton getInstance()  {  if (obj == null) {  // To make thread safe  synchronized (Singleton.class)  {  // check again as multiple threads  // can reach above step  if (obj == null)  obj = new Singleton();  }  }  return obj;  } }>

Vyhlásili sme obj nestály čo zaisťuje, že viaceré vlákna správne ponúkajú premennú obj, keď sa inicializuje do inštancie Singleton. Táto metóda drasticky znižuje réžiu volania synchronizovanej metódy zakaždým.

7. Použite metódu prípadu vzoru singleton

  • Databázové pripojenia: V aplikáciách, kde je vytváranie a správa databázových pripojení nákladnou operáciou, možno Singleton použiť na udržiavanie jediného databázového pripojenia v celej aplikácii.
  • Správa konfigurácie: Ak máte globálne konfiguračné nastavenia, ku ktorým majú mať prístup rôzne súčasti aplikácie, správca konfigurácie Singleton môže poskytnúť jediný prístupový bod k týmto nastaveniam.
  • Komponenty GUI: V prípade komponentov alebo ovládačov grafického používateľského rozhrania (GUI) môže Singleton pomôcť spravovať stav a činnosti používateľského rozhrania a poskytnúť tak jediný bod ovládania.
  • Správcovia zariadení: Vo vstavaných systémoch alebo aplikáciách interagujúcich s hardvérovými zariadeniami možno Singleton použiť na správu a riadenie prístupu k hardvérovým zariadeniam, aby sa predišlo konfliktom.
  • Tlačová služba: V systémoch, ktoré zahŕňajú tlač dokumentov alebo správ, môže tlačová služba Singleton koordinovať a spravovať tlačové úlohy, čím sa zabezpečí efektívne využitie tlačových zdrojov.

8. Výhody vzoru návrhu metódy Singleton:

  • Rieši kolízie mien: V scenároch, kde je potrebný jeden riadiaci bod, aby sa predišlo konfliktom alebo kolíziám pomenovaní, vzor Singleton zaisťuje, že existuje iba jedna inštancia s jedinečným názvom.
  • Dychtivá alebo lenivá inicializácia: Vzor Singleton podporuje dychtivú inicializáciu (vytvorenie inštancie pri načítaní triedy) aj lenivú inicializáciu (vytvorenie inštancie pri prvom vyžiadaní), čím poskytuje flexibilitu na základe prípadu použitia.
  • Bezpečnosť závitu: Správne implementované vzory Singleton môžu poskytnúť bezpečnosť vlákien tým, že zaistia, že inštancia je vytvorená atomicky a že viaceré vlákna neúmyselne nevytvoria duplicitné inštancie.
  • Znížená pamäťová stopa: V aplikáciách, kde je spotreba prostriedkov kritická, môže vzor Singleton prispieť k zníženiu pamäťovej stopy tým, že zabezpečí, že existuje iba jedna inštancia triedy.

9. Nevýhody Singleton Design Pattern

  • Ťažkosti pri testovaní: Keďže Singletony zavádzajú globálny stav, testovanie jednotiek môže byť náročné. Testovanie jedného komponentu v izolácii môže byť komplikovanejšie, ak sa spolieha na Singleton, pretože stav Singletonu môže ovplyvniť výsledok testov.
  • Problémy so súbežnosťou: Vo viacvláknovom prostredí sa môžu vyskytnúť problémy súvisiace s vytvorením a inicializáciou inštancie Singleton. Ak sa viaceré vlákna pokúsia vytvoriť Singleton súčasne, môže to mať za následok pretekanie.
  • Obmedzená rozšíriteľnosť: Vzor Singleton môže znížiť rozšíriteľnosť kódu. Ak sa neskôr rozhodnete, že potrebujete viacero inštancií triedy alebo chcete zmeniť logiku vytvárania inštancií, môže to vyžadovať značné prerobenie.
  • Globálna závislosť: Vzor Singleton vytvára globálnu závislosť, takže je ťažšie nahradiť Singleton alternatívnou implementáciou alebo použiť injekciu závislosti na poskytovanie inštancií.
  • Ťažko do podtriedy: Podtrieda Singleton môže byť náročná. Pretože konštruktor je zvyčajne súkromný, rozšírenie Singletonu si vyžaduje dodatočnú starostlivosť a nemusí dodržiavať štandardné vzory dedenia.
  • Správa životného cyklu: Vzor Singleton nemusí zvládnuť scenáre, v ktorých je potrebné inštanciu explicitne zničiť alebo resetovať. Riadenie životného cyklu Singletonu sa môže stať problémom.
  • Zneužívanie globálneho prístupového bodu: Globálny prístupový bod je síce výhodou, ale dá sa aj zneužiť. Vývojári môžu byť v pokušení používať Singleton na všetko, čo vedie k nadmernému využívaniu globálneho stavu a menej modulárnemu dizajnu.

10. Záver

Pre niektoré triedy je dôležité, aby mali presne jednu inštanciu. Hoci v systéme môže byť veľa tlačiarní, mal by existovať iba jeden spooler tlačiarní. Mal by existovať iba jeden súborový systém a jeden správca okien. Digitálny filter bude mať jeden A/D prevodník. Účtovný systém bude určený na obsluhu jednej spoločnosti. Ako zabezpečíme, aby trieda mala iba jednu inštanciu a aby bola inštancia ľahko dostupná? Globálna premenná sprístupňuje objekt, ale nebráni vám vytvárať inštanciu viacerých objektov.

Lepším riešením je, aby samotná trieda bola zodpovedná za sledovanie svojej jedinej inštancie. Trieda môže zabezpečiť, že nebude možné vytvoriť žiadnu inú inštanciu (zachytením požiadaviek na vytvorenie nových objektov) a môže poskytnúť spôsob prístupu k inštancii. Toto je vzor Singleton.