W tym wpisie po krótce zajmę się kolejnym konstrukcyjnym wzorcem projektowym. Tym razem będzie to Singleton
Singleton
jest to wzorzec, który gwarantuje posiadanie tylko jednej instancji danej klasy w całej aplikacji. Pozwala również na globalny dostęp do tej instancji.
Implementacja:
Singleton powinien składać się z kilku stałych elementów:
- słówka kluczowego sealed jako deklaracji klasy, aby uniemożliwić dziedziczenie po tej klasie
- statycznej, prywatnej instancji własnej klasy w postaci pola od nullowej wartości
- prywatnego konstruktora
- publicznej właściwości za pomocą której będziemy mogli pobrać istniejącą instancję lub stworzyć ją w przypadku gdy ta nie istnieje
Podstawowy kod jest prezentuje się następująco:
public sealed class Singleton
{
private static Singleton _instance = null;
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton ();
}
return _instance;
}
}
private Singleton ()
{
}
}
Jest to wersja wyjściowa dla tego wzorca. Oczywiście może on również zawierać metody. W tej formie posiada jednak dość poważną wadę – nie jest odporny na wielowątkowe zapytania. Istnieje bowiem prawdopodobieństwo, że kilka wątków odpytają naszą klasę w tym samym czasie i powstaną dwie instancje Singleton.
Można sobie z tym w dość prosty sposób poradzić zakładając tzw lock wewnątrz właściwości, która zapewnia dostęp do instancji klasy.
Poniżej przykładowy kod:
public sealed class SecuredSingleton
{
private static SecuredSingleton _instance = null;
private static readonly object _oLock = new object();
public static SecuredSingleton Instance
{
get
{
if (_instance == null)
{
lock(_oLock)
{
if(_instance == null)
_instance = new SecuredSingleton();
}
_instance = new SecuredSingleton ();
}
return _instance;
}
}
private SecuredSingleton ()
{
}
}
Zastosowanie:
Singleton może znaleźć zastosowanie między innymi jako mechanizm odpowiadający za logowanie pewnych zdarzeń w systemie.
Wady
Nie powinniśmy jednak nadużywać tego wzorca projektowego. Mimo że rozwiązuje trochę problemów, to jednak łamie kilka z podstawowych zasad dobrego programowania w tym dwie z zasady SOLID. Zasady jednej odpowiedzialności i zasady otwarte zamknięte. Poza tym kod w tej postaci jest ciężko rozszerzalny.