Thursday, 4 October 2018

Singleton Pattern

The one pattern you probably shouldn't be using except for when you should... The singleton pattern is often times considered a code smell, that is something that's indicative of something being poorly architected; that said i've used it i've seen it used and sometimes it makes sense especially in the sense of non web applications.

the definition of the singleton pattern: the singleton pattern ensures a class has only one instance, and provides a global point of access to it. that means that only one instance can and will exist with regards to a singleton class.


We can see from our class diagram that our singleton has a static field representing itself, a private constructor to prevent anyone from instantiating it and a static "GetInstance()" method that returns the static instance of our singleton.

using System;

namespace pav.singletonPattern
{
    class Singleton
    {
        static Singleton instance = new Singleton();
        private Singleton() { }
        public static Singleton GetInstance() => instance;
       
        public string SayHi() => "hi";
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Singleton.GetInstance().SayHi());
        }
    }
}

Now the above implementation of the singleton pattern seems rather silly, but let's say that for some reason we wanted to defer instantiation of our singleton till the future. well we could defer the instantiation of our instance until such a time that we needed it.

using System;

namespace pav.singletonPattern
{
    class Singleton
    {
        static Singleton instance;
        private Singleton() {}
        public static Singleton GetInstance() => instance = instance ?? new Singleton();
       
        public string SayHi() => "hi";
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Singleton.GetInstance().SayHi());
        }
    }
}


in the above when we call the "GetInstance()" function if the singleton has been instantiated we get the original instantiation however if it's null we instantiate it.

there is added complexity that is not covered here if you need to asynchronously do a lazy load, but that's a longer story for another day.