Singleton

Przeznaczenie

  • Gwarantuje, że dana klasa będzie miała tylko i wyłącznie jedną instancję obiektu i zapewnia globalny punkt dostępu do tej instancji

  • Wszystkie obiekty korzystające z danej klasy używają tego samego egzemplarza

Kontekst

  • W systemie istnieją obiekty, które z różnych powodów powinny występować tylko w jednym egzemplarzu

Problem

  • Chcemy utworzyć klasę, która może mieć tylko jeden egzemplarz instancji, dostępny dla klientów

Struktura

_images/singleton.png

Uczestnicy

  • Operacja Instance() pozwala klientowi dostać się do jedynej instancji klasy (uniqueInstance)

  • Instance() jest metodą statyczną

  • Singleton może być odpowiedzialny za tworzenie swojej własnej unikalnej instancji

Konsekwencje

  1. Kontrolowany dostęp do jedynego egzemplarza. Ponieważ klasa Singleton kapsułkuje swój jedyny egzemplarz, może ściśle kontrolować to, jak i kiedy klienci dostają się do niego.

  2. Możliwe udoskonalanie operacji i reprezentacji klasy Singleton. Możliwe jest tworzenie podklasy klasy Singleton. Łatwo można konfigurować aplikację za pomocą egzemplarza tej rozszerzonej klasy – wystarczy podać egzemplarz klasy, która jest potrzebna.

  3. Zmienna liczba egzemplarzy. Możliwa jest implementacja z większą liczbą egzemplarzy klasy.

  4. Większa elastyczność niż w wypadku implementacji wykorzystującej metody statyczne.

Implementacja

  1. Zagwarantowanie unikatowego egzemplarza:

  • prywatny konstruktor

  • prywatna statyczna właściwość inicjalizowana jedyną instancją klasy

  • publiczna właściwość lub metoda oferująca dostęp do jedynego egzemplarza obiektu klasy Singleton

  1. Tworzenie podklas klasy Singleton.

  2. Leniwa inicjalizacja instancji klasy.

  3. Singleton wielowątkowy – obsługa jednoczesnych wywołań Instance(). Wybór odpowiedniej implementacji wzorca Singleton w otoczeniu wielowątkowym powinien być poprzedzony szczegółową analizą wydajności aplikacji i ograniczeń zasobów.

// Singleton Meyersa
class Singleton
{
public:
    static Singleton& instance()
    {
        static Singleton instance_;
        return instance_;
    }
    void do_something();
private:
    Singleton() {};
    Singleton(const Singleton&) {};
    ~Singleton() {}
};
Singleton::instance().do_something();
Singleton& singleObject = Singleton::instance();
singleObject.do_something();

Wzorce pokrewne

Z użyciem wzorca Singleton można implementować wiele wzorców, m.in. Abstract Factory, Builder, Prototype.

Podsumowanie

  1. Singleton gwarantuje, że zostanie utworzony tylko jeden egzemplarz danej klasy.

  2. Wszystkie obiekty korzystające z danej klasy używają tego samego egzemplarza.