czwartek, 5 lipca 2012

[Wzorce projektowe] Singleton

Analogia z życia:

Każde dziecko wie, że nieodłączną częścią każdego samochodu jest kierownica. Samochód zawiera dokładnie jedną kierownicę. Kierownica może być używana tylko przez jedną osobę, lub w ogóle nie używana. Gdyby kilka osób zaczęło kręcić kierownicą podczas jazdy to nietrudno sobie wyobrazić do czego by to doprowadziło. Gdyby samochód miał więcej kierownic. W najlepszym wypadku doszło by do czegoś takiego :-):



Zastosowanie:

Singletony tworzy się, gdy zachodzi potrzeba stworzenia dokładnie jednej instancji danej klasy. Dodatkowo wprowadza się blokowanie dwufazowe - zabezpieczenie instancji przed dostępem z wielu wątków. Obiekty - singletony podczas tworzenia nie potrzebują by przekazywać parametry za pomocą konstruktora. Czasami warto także zastanowić się nad stworzeniem singletonu gdy samo tworzenie obiektu jest kosztowne czasowo, a nie jest potrzebne wiele instancji.

Zasada działania:


Zazwyczaj tworzy się klasę zawierającą propercję lub polę pewnego typu. Klasa zewnętrzna posiada prywatny konstruktor i metodę zwracającą instancję obiektu z pola / propercji. Jeśli obiekt nie został wcześniej zainicjowany, to tworzy się instancję, która później jest zwracana przy każdym wywołaniu tej metody. Można użyć także klas statycznych, ale jest to odradzane ze względu na problemy z testowaniem i brak możliwości dziedziczenia.

Przykład:

Interfejs do zapisywania zmian do jakiegoś rejestru np logowanie wyjątków.

Przykład implementacyjny:

Poniższy singletonu wydaje się być optymalny ze względu na wydajność dla platformy .NET.




    public class ThreadSafeSingleton
    {
        private ThreadSafeSingleton()
        {
            
        }

        public static ThreadSafeSingleton Instance 
        {
            get { return NestedClass.instance; }
        }

        public void SayHello()
        {
            Console.WriteLine("How are you ?");
        }

        public class NestedClass
        {
            static NestedClass()
            {
            }

            internal static readonly ThreadSafeSingleton instance =
                new ThreadSafeSingleton();
        }
    }

class Program
    {
        static void Main(string[] args)
        {
            var inst = ThreadSafeSingleton.Instance;
            inst.SayHello();

        }
    }


Prywatny konstruktor zabrania tworzenia obiektów klasy. Statyczna propercja gwarantuje, że przekazywana będzie jedna referencja przy każdym wywołaniu, natomiast dzięki statycznemu konstruktorowi klasy zagdnieżdżonej obiekt zostanie zainicjowany dopiero przy pierwszym jego wywołaniu (Lazy Loading). Pole readonly zapewnia bezpieczeństwo przy pracy wielowątkowej i jest to podejście szybsze od stosowania instrukcji lock.

Linki:

1.Readonly a thread safe 

Brak komentarzy:

Prześlij komentarz