Tuesday, August 15, 2017

Difference between singleton object and static class members

Long back during one of interview this question came. Why should we use singleton instead of static class with members? Are they same? Some thoughts on the same below.

Singleton objects and static classes have their own purposes. The difference between those may be too little but there are differences. Lets see what is meant by these 2 varieties.

class Context
{
        private static Context internalContext = new Context();
        private Context() { }
        public static Context Singleton { get { return internalContext; } }
        public string GetEnvironmentSettings() { return "settings"; }
}
public void DoBusinessOperation()
{
        string settings= Context.Singleton.GetEnvironmentSettings();
}


static class StaticContext
{
        public static string GetEnvironmentSettings() { return "settings"; }
}
public void DoBusinessOperation()
{
        string settings = StaticContext.GetEnvironmentSettings();
}

Technically the above 2 methods achieve same thing. But we have to understand when should we use the singleton class based approach and static class members approach.

Singleton object can be inherited static class cannot.

The above code was running perfect in an web application which was hosted in onpremise data center. Then the cloud migration came and the strategy is to support onpremise and Azure cloud for a period of 1 year and after that Azure only. Suppose getting environment settings is different in Azure than onpremise, how can we make this code support the scenario without having different codebases?

Don't take the above scenario as is. Just assume we came across a scenario where the behavior of Singleton has to change based on running environment and how to support it without having to maintain many code bases?

Yes its a solved problem. We should use inheritance and change behavior based on the environment. If we go with Singleton model we can have the class derived from another base and expose the base to outside. Below goes the code snippet.

class Context
    {
        private static Lazy<Context> internalContext = new Lazy<Context>(() =>
        {
            //Logic to create the correct object based on criteria. Environment in this case.
            return new AzureContext();
        });

        public static Context Singleton { get { return internalContext.Value; } }
        public virtual string GetEnvironmentSettings() { return "settings"; }
        private class OnPremiseContext : Context
        {
            public override string GetEnvironmentSettings()
            {
                return "settings";
            }
        }
        private class AzureContext : Context
        {
            public override string GetEnvironmentSettings()
            {
                return "Azure settings";
            }
        }
    }


The above code is just for demonstrating the advantage of using Singleton object over static class members.

Singleton can be disposed,static class cannot

In reality we may not meet a situation where a Singleton object needs to be disposed. For argument sake we can say that if we need Singleton object at a thread level (thread static), this is useful. Once that thread completes execution we can dispose the object.

Passing singleton object as param, static class cannot

This is similar to the inheritance scenario but another advantage of using Singleton object. Ideally Singleton is a mechanism where we can access it from anywhere in the code by using its class name. It doesn't need to be passed into a function. We we want to make our functions testable, we can think of accepting the Singleton objects. Also we can use dependency injection mechanism to unit test the code without any overhead of actual singleton object.

There are many other differences between these models but mainly depends on these 3. Since the Singleton is an object it can be cloned but static class cannot. Storage of data in process memory, performance between these 2 models etc...are some other differences.

References

https://stackoverflow.com/questions/519520/difference-between-static-class-and-singleton-pattern
http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

No comments: