Singleton

Situace

V systému má existovat třída, která může mít nanejvýš jednu globální instanci a zároveň centralizuje k této instanci přístup.

Problém

Teoreticky je možné vytvořit instanci libovolné třídy na libovolném místě. Toto chování není žádoucí u třídy, která může mít instanci jen jednu a navíc centrálně spravovanou.

Řešení

Skrytím konstruktoru zvolené třídy se omezí místa, na kterých je možné její instance vytvářet. Dále se ve třídě vytvoří statická proměnná obsahující globální sdílenou instanci dané třídy. Do této proměnné se instance třídy může přiřadit hned, nebo až v případě potřeby (princip lazy loading).

UML diagramy

diagram tříd

Implementace

Následuje jednoduchý příklad implementace tohoto vzoru v programovacím jazyce Java.

Singleton

kód v jazyce Java - Zobrazit

  1. /**
  2.  * Třída, která má globálně nejvýše jednu instanci.
  3.  *
  4.  * @author Vojtěch Hordějčuk
  5.  */
  6. public class Singleton
  7. {
  8.   /**
  9.    * jedinečná globální instance třídy
  10.    */
  11.   private static Singleton instance = null;
  12.  
  13.   /**
  14.    * Vrátí jedinečnou globální instanci této třídy. Pokud instance neexistuje,
  15.    * bude vytvořena. Aby byla metoda bezpečná, je nutné přidat kvalifikátor
  16.    * "synchronized".
  17.    *
  18.    * @return jedinečná globální instance třídy
  19.    */
  20.   public static Singleton getInstance()
  21.   {
  22.     if (Singleton.instance == null)
  23.     {
  24.       // globální instance neexistuje, je třeba ji vytvořit
  25.  
  26.       Singleton.instance = new Singleton();
  27.     }
  28.  
  29.     return Singleton.instance;
  30.   }
  31.  
  32.   /**
  33.    * Konstruktor nesmí být veřejný, aby jej nebylo možné volat, a tak obcházet
  34.    * výchozí mechanismus.
  35.    */
  36.   private Singleton()
  37.   {
  38.     // ...
  39.   }
  40. }
Test

kód v jazyce Java - Zobrazit

  1. public static void main(String[] args)
  2. {
  3.   // získat globální instanci třídy a vykonat akci
  4.  
  5.   Singleton.getInstance().doSomething();
  6. }

Reference