wtorek, 19 lutego 2013

Singleton

Singleton jest jednym z kreacyjnych wzorców projektowych, który ma na celu ograniczenie możliwości tworzenia obiektów danej klasy do jednej instancji oraz zapewnienie globalnego dostępu do stworzonego obiektu. Możliwe jest również zmodyfikowanie tego wzorca do określenia maksymalnej liczby możliwych obiektów, jakie mogą istnieć w systemie. Idea polega na stworzeniu klasy przechowującej żądania powstania większej liczby instancji oraz zapewniającej łatwy dostęp do tej jedynej istniejącej.

Struktura

 


Uczestnicy


Uczestnikiem wzorca jest tylko jedna klasa – Singleton. Zaimplementowana jest w niej statyczna metoda getInstance(), która przy wywołaniu w pierwszej kolejności sprawdza, czy istnieje już instancja tej klasy – jeżeli nie, tworzy ją. W dalszej kolejności instancja zwracana jest przez referencję. Instancja przechowywana jest w prywatnym lub chronionym, statycznym atrybucie, do którego dostęp ma tylko metoda getInstance(). Metoda getInstance() jest jedyną drogą pozyskania instancji klasy Singleton. Ma to na celu uniemożliwienie tworzenia kolejnych instancji. Konstruktor tej klasy ma widoczność prywatną lub chronioną. Klient nie widzi, czy instancja już istnieje, czy jest tworzona. 

Konsekwencje


Zalety:
  • Singleton może być zmodyfikowany do zarządzania większą liczbą instancji;
  • klasa może kontrolować liczbę własnych instancji;
  • kontrola sposobu uzyskiwania instancji obiektu (poprzez statyczną metodę);
  • globalne uzyskiwanie instancji obiektu (z każdego miejsca kodu);
  • proces pobierania/tworzenia instancji jest niewidoczny dla klienta;
  • tworzenie nowej instancji ma charakter leniwy - zachodzi dopiero przy pierwszej próbie użycia - nie zajmuje niepotrzebnie zasobów;
  • gwarancja, że obiekt zostanie utworzony i usunięty tylko raz - szczególne ważne w przypadku zarządzania dostępem do globalnego zasobu, np. połączenia z bazą danych.
Wady:
  • Brak możliwości dynamicznej zmiany liczby możliwych instancji w systemie;
  • utrudnienie w testowaniu z powodu wprowadzenia globalnego stanu;
  • słabo rozszerzalny.
Stosowanie tego wzorca w systemach wielowątkowych ma szczególne znaczenie. Powinien być zaimplementowany dodatkowo mechanizm synchronizacji dostępu w celu wykluczenia możliwości stworzenia kilku instancji Singletonu przez niezależne od siebie wątki.

Zastosowanie


  • wszędzie tam, gdzie potrzebna jest jedna jedyna instancja danej klasy lub jest z góry ustalona maksymalna liczba jej instancji;
  • gdy potrzebujemy globalnego dostępu do instancji klasy.

Przykład


  • manager plików;
  • kolejka do urządzenia peryferyjnego (np. drukarki);
  • obiekt konfiguracji aplikacji.


Przykładowy kod:

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;
}

//sposób tworzenia instancji:
Singleton = Singleton::getInstance();



Brak komentarzy:

Prześlij komentarz