Singleton – konstrukcyjny wzorzec projektowy

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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *