logo

Návrhový vzor metody Singleton

Singleton Pattern je pravděpodobně nejpoužívanější designový vzor. Je to jednoduchý vzor, ​​snadno pochopitelný a použitelný. Někdy se používá v nadměrné míře a ve scénářích, kde to není vyžadováno. V takových případech převažují nevýhody jeho používání nad výhodami, které přináší. Z tohoto důvodu je singleton vzor někdy považován za antipattern nebo pattern singleton .

Singleton-Metoda-Design-Pattern



Důležitá témata pro návrhový vzor Singleton Method

1. Co je návrhový vzor metody Singleton?

Metoda Singleton neboli Singleton Design pattern je jedním z nejjednodušších návrhových vzorů. Zajišťuje, že třída má pouze jednu instanci, a poskytuje k ní globální bod přístupu.

2. Kdy použít Singleton Method Design Pattern?

Návrhový vzor metody Singleton použijte, když:



jarní poznámky bot
  • Musí existovat přesně jedna instance třídy a musí být přístupná klientům ze známého přístupového bodu.
  • Když by jediná instance měla být rozšiřitelná pomocí podtříd a klienti by měli mít možnost používat rozšířenou instanci bez úprav
  • Třídy Singleton se používají pro protokolování, objekty ovladačů, ukládání do mezipaměti a fond vláken, databázová připojení.

3. Typy inicializace Singletonu

Třídu Singleton lze vytvořit dvěma způsoby:

  • Předčasná inicializace: V této metodě je třída inicializována, ať už má být použita nebo ne. Hlavní výhodou této metody je její jednoduchost. Třídu zahájíte v době načítání třídy. Jeho nevýhodou je, že třída je vždy inicializována, ať už je používána nebo ne.
  • Líná inicializace: V této metodě se třída inicializuje pouze tehdy, když je to vyžadováno. Může vás to zachránit před vytvářením instance třídy, když ji nepotřebujete. Obecně se líná inicializace používá, když vytváříme singletonovou třídu.

4. Klíčová součást návrhového vzoru metody Singleton:

Klíčová-složka-jednotlivého-návrhového-vzoru-(1)

4.1. Statický člen:

Vzor Singleton nebo vzor Singleton používá v rámci třídy statický člen. Tento statický člen zajišťuje, že paměť je přidělena pouze jednou, a zachovává tak jedinou instanci třídy Singleton.



Jáva
// Static member to hold the single instance private static Singleton instance;>

4.2. Soukromý konstruktér:

Vzor Singleton nebo vzor singleton obsahuje soukromý konstruktor, který slouží jako barikáda proti externím pokusům o vytvoření instancí třídy Singleton. To zajišťuje, že třída má kontrolu nad procesem vytváření instance.

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

4.3. Statická tovární metoda:

Rozhodujícím aspektem vzoru Singleton je přítomnost statické tovární metody. Tato metoda funguje jako brána, která poskytuje globální přístupový bod k objektu Singleton. Když někdo požaduje instanci, tato metoda buď vytvoří novou instanci (pokud žádná neexistuje), nebo vrátí existující instanci volajícímu.

dynamické pole v Javě
Jáva
// 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. Implementace návrhového vzoru Singleton Method

Implementace Singleton Design Pattern nebo Pattern Singleton je popsána v následujícím diagramu tříd:

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

Implementace návrhového vzoru Singleton Method

Implementace vzoru singleton Design je velmi jednoduchá a skládá se z jediné třídy. Aby bylo zajištěno, že instance singleton je jedinečná, měly by být všechny konstruktory singleton nastaveny jako soukromé. Globální přístup se provádí prostřednictvím statické metody, ke které lze globálně přistupovat k jedné instanci, jak je znázorněno v kódu.

Jáva
/*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ýstup
Singleton is Instantiated. Somethong is Done.>

Metodou getInstance zkontrolujeme, zda je instance nulová. Pokud instance není null, znamená to, že objekt byl vytvořen dříve; jinak jej vytvoříme pomocí operátoru new.

6. Různé způsoby implementace návrhového vzoru metody Singleton

Někdy potřebujeme mít pouze jednu instanci naší třídy, například jediné DB připojení sdílené více objekty, protože vytvoření samostatného DB připojení pro každý objekt může být nákladné. Podobně může být v aplikaci jeden správce konfigurace nebo správce chyb, který řeší všechny problémy namísto vytváření více správců.

Klasická implementace

metody v Javě

Podívejme se na různé možnosti návrhu implementace takové třídy. Pokud dobře ovládáte statické proměnné třídy a modifikátory přístupu, neměl by to být obtížný úkol.

Metoda 1 – Klasická implementace || Pro implementaci nastavte getInstance() na statickou Návrhový vzor metody Singleton

Jáva
// 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;  } }>

Zde jsme prohlásili getInstance() static, abychom jej mohli volat bez vytváření instance třídy. Poprvé getInstance() se nazývá, že vytvoří nový singletonový objekt a poté pouze vrátí stejný objekt.

Poznámka: Singleton obj se nevytvoří, dokud jej nebudeme potřebovat a nezavoláme getInstance() metoda. Tomu se říká líná konkretizace. Hlavním problémem výše uvedené metody je, že není bezpečná pro vlákna. Zvažte následující sekvenci provádění.

Java řetězec ve srovnání

Tato sekvence provádění vytvoří dva objekty pro singleton. Proto tato klasická implementace není bezpečná pro vlákna.

Metoda 2 || Proveďte synchronizaci getInstance() pro implementaci Návrhový vzor metody Singleton

Jáva
// 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;  } }>

Zde použití synchronizovaného zajistí, že se může spustit vždy pouze jedno vlákno getInstance() . Hlavní nevýhodou této metody je, že použití synchronizované pokaždé při vytváření singleton objektu je drahé a může snížit výkon vašeho programu. Pokud však výkon getInstance() není pro vaši aplikaci rozhodující, tato metoda poskytuje čisté a jednoduché řešení.

Metoda 3 – Eager Instanciation || Implementace jednobarevného návrhového vzoru založená na statickém inicializátoru

Jáva
// 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; } }>

Zde jsme vytvořili instanci singletonu ve statickém inicializátoru. JVM spustí statický inicializátor, když je třída načtena, a proto je zaručeno, že je bezpečné pro vlákna. Tuto metodu použijte pouze v případě, že je vaše třída singleton lehká a používá se po celou dobu provádění vašeho programu.

Metoda 4 – nejúčinnější || Použijte Double Checked Locking k implementaci jednoduchého návrhového vzoru

Pokud si všimnete, že jakmile je objekt vytvořen, synchronizace již není užitečná, protože nyní obj nebude mít hodnotu null a jakákoli sekvence operací povede ke konzistentním výsledkům. Takže zámek na getInstance() získáme pouze jednou, když je obj null. Tímto způsobem synchronizujeme pouze první cestu, přesně to, co chceme.

Jáva
// 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 jsme obj nestálý což zajišťuje, že více vláken nabízí proměnnou obj správně, když je inicializována do instance Singleton. Tato metoda výrazně snižuje režii volání synchronizované metody pokaždé.

7. Use Case of Pattern Singleton Method

  • Databázová připojení: V aplikacích, kde je vytváření a správa databázových připojení nákladná operace, lze Singleton použít k udržení jediného databázového připojení v celé aplikaci.
  • Správa konfigurace: Máte-li globální konfigurační nastavení, ke kterému mají mít přístup různé součásti aplikace, správce konfigurace Singleton může poskytnout jediný bod přístupu k těmto nastavením.
  • Komponenty GUI: Pro komponenty nebo řadiče grafického uživatelského rozhraní (GUI) může Singleton pomoci řídit stav a akce uživatelského rozhraní a poskytnout jediný bod ovládání.
  • Správci zařízení: Ve vestavěných systémech nebo aplikacích interagujících s hardwarovými zařízeními lze Singleton použít ke správě a řízení přístupu k hardwarovým zařízením, aby se předešlo konfliktům.
  • Tisková služba: V systémech, které zahrnují tisk dokumentů nebo zpráv, může tisková služba Singleton koordinovat a spravovat tiskové úlohy a zajistit tak efektivní využití tiskových zdrojů.

8. Výhody vzoru návrhu metody Singleton:

  • Řeší kolize jmen: Ve scénářích, kde je zapotřebí jeden řídicí bod, aby se zabránilo konfliktům nebo kolizím pojmenování, vzor Singleton zajišťuje, že existuje pouze jedna instance s jedinečným názvem.
  • Dychtivá nebo líná inicializace: Vzor Singleton podporuje jak dychtivou inicializaci (vytvoření instance při načtení třídy), tak línou inicializaci (vytvoření instance, když je poprvé požadována), což poskytuje flexibilitu na základě případu použití.
  • Bezpečnost závitu: Správně implementované vzory Singleton mohou zajistit bezpečnost vláken a zajistit, že instance je vytvořena atomicky a že více vláken neúmyslně nevytváří duplicitní instance.
  • Snížená paměťová stopa: V aplikacích, kde je spotřeba prostředků kritická, může vzor Singleton přispět ke snížení paměti tím, že zajistí, že existuje pouze jedna instance třídy.

9. Nevýhody návrhového vzoru Singleton

  • Obtíže při testování: Protože Singletony zavádějí globální stav, testování jednotek může být náročné. Testování jedné součásti v izolaci může být složitější, pokud se spoléhá na Singleton, protože stav Singletonu může ovlivnit výsledek testů.
  • Problémy souběžnosti: V prostředí s více vlákny mohou nastat problémy související s vytvořením a inicializací instance Singleton. Pokud se více vláken pokusí vytvořit Singleton současně, může to vést ke konfliktům.
  • Omezená rozšiřitelnost: Vzor Singleton může snížit rozšiřitelnost kódu. Pokud se později rozhodnete, že potřebujete více instancí třídy nebo chcete změnit instanční logiku, může to vyžadovat značné refaktorování.
  • Globální závislost: Vzor Singleton vytváří globální závislost, což ztěžuje nahrazení Singleton alternativní implementací nebo použití injekce závislostí pro poskytování instancí.
  • Těžko do podtřídy: Podtřída Singleton může být náročná. Protože konstruktor je obvykle soukromý, rozšíření Singletonu vyžaduje další péči a nemusí se řídit standardními vzory dědičnosti.
  • Správa životního cyklu: Vzor Singleton nemusí zpracovat scénáře, kdy je třeba instanci explicitně zničit nebo resetovat. Správa životního cyklu Singletonu se může stát problémem.
  • Zneužití globálního přístupového bodu: Globální přístupový bod je sice výhodou, ale může být také zneužit. Vývojáři mohou být v pokušení používat Singleton pro všechno, což vede k nadměrnému využívání globálního stavu a méně modulárnímu designu.

10. Závěr

Je důležité, aby některé třídy měly přesně jednu instanci. Přestože v systému může být mnoho tiskáren, měla by existovat pouze jedna zařazovací služba tiskáren. Měl by existovat pouze jeden souborový systém a jeden správce oken. Digitální filtr bude mít jeden A/D převodník. Účetní systém bude určen pro obsluhu jedné společnosti. Jak zajistíme, aby třída měla pouze jednu instanci a aby byla instance snadno dostupná? Globální proměnná zpřístupňuje objekt, ale nebrání vám vytvářet instanci více objektů.

Lepším řešením je pověřit třídu samotnou odpovědnou za sledování své jediné instance. Třída může zajistit, že nelze vytvořit žádnou jinou instanci (zachycením požadavků na vytvoření nových objektů), a může poskytnout způsob přístupu k instanci. Toto je vzor Singleton.