Wzorzec projektowy Singleton

Przeznaczenie

  • przeznaczony do ograniczania możliwości tworzenia obiektów danej klasy do jednej instancji oraz zapewnienie globalnego punktu dostępu do niej
  • używany w sytuacji, gdy istnieje potrzeba stworzenia klasy, która posiadałaby wyłącznie jedną instancję
  • użycie zamiast obiektu globalnego - nie zaśmiecany wtedy globalnej przestrzeni nazw różnymi nazwami obiektów

Motywacja

Singleton polega na stworzeniu klasy, ktora przechwytuje żądania powstania liczniejszych instancji,oraz zapewnia łatwy dostęp do tej jedynej istniejącej
Jedyna instancja jest rozszerzalna dla jej podklas, w ktorych można jej używać bez modyfikacji kodu.

Przykłady użycia: w systemie może występować tylko jeden manager okien, jedyny punkt dostępu do baz danych, jedna kolejka do jednej drukarki.

Konsekwencje

  • Kontrolowany dostęp do jedynej instancji
  • Zredukowana przestrzeń nazw
  • Pozwala na zwiększenie dozwolonej ilości instancji

Struktura

Implementacja

Kod singletonu w Java:

public class Singleton {
private static volatile Singleton INSTANCE;

private Singleton() {}
public static Singleton getInstance() {
    if (INSTANCE == null)
    synchronized(Singleton.class) {
         if (INSTANCE == null)
             INSTANCE = new Singleton();
}
     return INSTANCE;
}

Singleton ma zdefiniowaną statyczną metodę zwracającą jedyny obiekt klasy. Samo napisanie metody singleton-u nie wystarczy. Po napisaniu tej metody zmienia się sposób tworzenia instancji klasy. Zamiast: Singleton= new Singleton( ); Instancje tworzy się w ten sposób: Singleton = Singleton::getInstance ();

Zalety

Kontrolowany dostęp w odróżnieniu od obiektu globalnego. Gwarancja, że obiekt powstanie i zostanie zniszczony tylko raz - ta własność jest szczególnie ważna na systemów gdzie Singleton zarządza globalnym zasobem, np. połączeniem z bazą danych

Wady

Często nieumiejętnie stosowany: nie zrozumiałym jest tworzenie Singletonu zawierającego zmienne publiczne, lub stałe. Uzasadnione jest użycie Singletonu zawierającego stałe, gdy te stałe są wprowadzane w trakcie wykonywania programu. Gdy znamy wartości stałych przed wykonaniem należy użyć statycznych pól finalnych.

Inną powszechną wadą jest tworzenie zbyt dużych klas singletonów (tzw. Klas boskich) reprezentujących cały system, np. klasa system agregująca wszystkie klasy.

Przykład:

Klasycznym przykładem singletonu jest klasa Toolbox, posadająca metodę getDefaultToolbox(), która zwraca egzemplarz klasy Toolbox