Wzór twórczy: Singleton
W tym artykule omówiono, w jaki sposób wzorzec Singleton wymusza, aby tylko jedna instancja klasy kiedykolwiek została wyprodukowana i istniała przez cały okres istnienia aplikacji.
Co to jest?
Singleton to wzorzec projektowy używany do tworzenia jedynej instancji klasy. Wzorzec singleton jest zwykle używany, gdy istnieje kilka przykładów, w których powinna istnieć tylko jedna instancja klasy i wymuszane jest ograniczenie. Na przykład pamięci podręczne, pule wątków i rejestry powinny mieć tylko jedną instancję.
Uczyń konstruktora prywatnym, aby mieć pewność, że tworzony jest tylko jeden obiekt klasy. W ten sposób tylko członkowie klasy mają dostęp do prywatnego konstruktora i nikt inny.
W prawdziwym świecie wzorzec Singleton zapewnia, że istnieje tylko jedna instancja klasy i oferuje globalny punkt dostępu do niej.
Diagram klas
Diagram klas zawiera tylko jedną jednostkę.
Singel
Przykład
Załóżmy, że chcemy w naszym oprogramowaniu wymodelować oficjalny samolot prezydenta Stanów Zjednoczonych o nazwie Airforce One. Klasa Singleton jest najlepiej dopasowaną reprezentacją jednostki z tylko jedną instancją.
Oto kod naszej klasy singleton:
Wielowątkowość i Singleton
Ten kod działa tak długo, jak długo aplikacja jest jednowątkowa. Jeśli jednak wiele wątków uzyskuje dostęp do tej klasy, istnieje możliwość utworzenia różnych obiektów.
Na przykład:
- Wątek A wywołuje metodę
getInstancei stwierdza, żeonlyInstancema wartość null; jednak zanim będzie mógł utworzyć instancję, jest przełączany kontekst. - Teraz pojawia się wątek B i wywołuje
getInstance, co zwracaAirforceOneobiekt. - Jeśli wątek A zostanie ponownie zaplanowany, zaczyna się psota. Wątek przeszedł już sprawdzanie warunku if-null i przystąpi do tworzenia nowego
AirforceOneobiektu i przypisania go doonlyInstance.AirforceOneTeraz na wolności istnieją dwa różne obiekty, jeden z wątkiem A i jeden z wątkiem B.
- Dodając
synchronizeddogetInstance()metody, możesz osiągnąć bezpieczeństwo gwintu. - Inną opcją jest statyczna inicjalizacja instancji, gwarantująca bezpieczeństwo wątków.
Dwukrotnie sprawdzone blokowanie
Istnieją dwa istotne problemy z opisanymi powyżej podejściami: synchronizacja jest kosztowna, a inicjalizacja statyczna tworzy obiekt, nawet jeśli nie jest on używany w określonej aplikacji. Jeśli tworzenie obiektu jest drogie, inicjalizacja statyczna może kosztować nas wydajność.
Powyższe rozwiązanie oznacza, że instancja singletonu jest niestabilna. Jednak ta implementacja metodologii JVM volatilenie będzie działać poprawnie w przypadku podwójnego sprawdzania blokowania i będziesz potrzebować innego podejścia do tworzenia singletonów.
Podwójnie sprawdzany idiom blokujący jest obecnie uważany za antywzorzec, a jego użyteczność przede wszystkim przeminęła, ponieważ czasy uruchamiania maszyny JVM przyspieszyły.
Inne przykłady
Java API udostępnia nam następujące singletony:
java.lang.Środowisko wykonawcze
java.awt.Desktop
Zastrzeżenia
Możesz podklasować klasę singleton, chroniąc konstruktora zamiast private. Jednak w każdych okolicznościach istnieją lepsze wybory niż ten. W takich sytuacjach programiści mogą utworzyć rejestr pojedynczych elementów dla wszystkich podklas. Metoda getInstance może przyjąć parametr lub użyć zmiennej środowiskowej, aby zwrócić żądany obiekt singleton. Rejestr utrzymuje mapowanie nazw łańcuchów na pojedyncze obiekty.

![Czym w ogóle jest lista połączona? [Część 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































