Singleton – Czego jeszcze o nim nie wiesz?

Singleton

Singleton – kreacyjny wzorzec projektowy, dający pewność, że klasa ma tylko jedną, globalnie dostępną instancję.

Przeznaczenie i warunki stosowania

Warunki jakie należy spełnić aby używać wzorca:

  • Musi istnieć dokładnie jeden egzemplarz klasy udostępniany klientom
  • W przypadku rozszerzenia jedynej klasy przez stworzenie podklas, klienci powinno nadal móc korzystać bez wprowadzania zmian w swoim kodzie.

Singleton może zostać wykorzystany do implementacji innych wzorców (o czym w kolejnych wpisach):

Życiowa analogia

Dyrekcja szkoły. Szkoła może mieć tylko jedną dyrekcję. Niezależnie od osób w dyrekcji, tytuł „Dyrekcja szkoły” jest globalnym punktem dostępu do Dyrekcji i dotyczy zawsze tej samej dyrekcji (w przestrzeni danej szkoły).

Singleton Struktura

  • Definiuje operację GetInstance() umożliwiającą dostęp do niepowtarzalnego egzemplarza klasy
  • Odpowiada za tworzenie własnego niepowtarzalnego egzemplarza
Singleton - struktura wzorca projektowego
Struktura Wzorca Singleton

Singleton Konsekwencje Stosowania

Pozytywne:

  • zapewnia kontrolę dostępu do jedynego egzemplarza
  • obiekt jest tworzony dopiero gdy zostanie zażądany po raz pierwszy
  • pozwala zmniejszyć przestrzeń nazw – ogranicza zaśmiecanie przestrzeni nazw zmiennymi globalnymi
  • umożliwia określenie limitu egzemplarzy (domyślnie 1) – wystarczy zmodyfikować operację GetInstance()

Negatywne

I tutaj ukazuje się prawdziwe oblicze Singletonu:

  • łamanie dobrych praktyk SOLID (szczególnie *S* – single responsibility principle, czyli zasada pojedynczej odpowiedzialności)
  • nie istnieje dobry sposób „zniszczenia” lub zwolnienia Singletonu
  • utrudnione testowanie (szczególnie w przypadku aplikacji wielowątkowych)
  • stosowanie go jako zamiennik zmiennej globalnej
  • klasa dziedzicząca z Singletonu, nie jest Singletonem, potrzebny jest dodatkowy kod
  • w większości wywołań metody GetInstance(), instrukcja if(null) jest bezużyteczna, co może odbijać się na wydajności przy wielu wywołaniach

Singleton Implementacja

W najprostszym wydaniu implementacja wzorca Signleton, opiera się o:

  • Prywatne statyczne pole reprezentujące żądany obiekt (line 4).
  • Publiczną statyczną metodę zwracającą jedyną instancję klasy, tworzącą ją w przypadku jej braku (line 6).

W bardziej rozbudowanych modelach, można spotkać również:

1. Blokadę wątku, przed stworzeniem nowej instancji klasy (patrz linia 10). Zabezpiecza to nasz model przed równoczesnym wywołaniem GetInstance() przez dwa wątki w tym samym czasie i ponownego stworzenia/nadpisania obiektu (tutaj loggera).

2. „Ukryty” konstruktora klasy: protected SingletonLoggerExample() – blokując możliwość tworzenia obiektu przez domyślny konstruktor publiczny.

3. Rzucanie wyjątkiem w prywatnym w powyższym konstruktorze, uniemożliwiając przypadkowe wywołanie go z wykorzystaniem refleksji.

Podsumowanie

Niewątpliwie Singleton jest dobrym materiałem treningowym do zrozumienia zagadnień związanych z programowaniem, jednak nie cieszy się powodzeniem wśród doświadczonych programistów. Głównie ze względu na negatywne konsekwencje jakie ze sobą niesie jego implementacja.
Prostym i dość oczywistym przykładem prawidłowego zastosowania wzorca jest prosty logger. Niestety może się to zmienić w przypadku bardziej złożonych schematów rejestrowania.

Ważne abyś samemu zastanowił się i przemyślał, czy Singleton to wzorzec który pasuje do Twojego problemu, czy może inny Wzorzec Projektowy byłby lepszy, a może prosty kod będzie wystarczający?

Zainteresował Cię materiał? Zapraszam do listy mailowej, by być na bieżąco z kolejnymi wpisami.

Subscribe
Powiadom o
guest
0 komentarzy
Inline Feedbacks
View all comments