Saturday, November 13, 2010

Singleton Vs Static

The question is really simple, why do I need a Singleton? Why a class with static methods/variables will not do the same what a singleton is supposed to do?

I never thought about that. So, I googled for “Singleton vs Static” and here is the excerpt from the results.

A class with static utility methods can be used for exposing standalone methods (e.g. utility/helper methods). Such a class holds little or no state. On the other side a singleton, should be used whenever there is a state to store. The main advantage of Singleton over static (i.e. a class with static utility methods) is, it may use polymorphism. Ideally, a singleton should return different implementations of the class at runtime depending on the use case. To explain it further, let’s have a look of java.lang.Runtime class. The description of the class says:

Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.

Actually, Runtime.getRuntime() method returns a singleton object - an object which depends on the particular platform over which the JVM is running. Thus, different implementation of JVM will provide an instance of different subclasses of Runtime itself, which is designed to run on that specific platform/OS.

It sounds similar to factory! Is Singleton a factory? The idea is, Singletons can be extended into a factory. The whole process of object creation is abstracted from the API user. And hence it can be maintained/extended/changed easily. But, the fundamental difference between these two should also be kept in mind. A factory returns a new instance on each invocation of the getter method, whereas a Singleton always returns the same instance of the class. But, in most of the cases we don’t use Singleton pattern in such a way and hence Singletons does not really offer much advantage over the static.

In addition to this, if I have a Singleton, I can implement interfaces and extend classes. Lazy initialization of Singletons are possible, i.e. the Singleton object may have a shorter life time than the application containing it. MySingleton.getInstance() returns an actual object. These advantages are missing with a class with static utility methods.

To summarize, if you want to write a class with some stateless (or almost stateless) static methods, go for a class with static methods and static variables. If you need something more, as I have mentioned before, then Singleton should be your choice. But, remember, before banking on the static, analyze and think twice. It should never be the case that in future you have to rewrite the code and go back to the Singleton!

So, the final question. Is Singleton a pattern with all good? I am afraid. The answer is NO!


Further Reading:

  • Sun Java Forum has a nice discussion on this . But, after migration to Oracle, I am not able to find it out. However a simple google search should do!
  • When is a Singleton not a Singleton?

6 comments:

  1. Nice Article. Although I have little bit different view on the comment "It sounds similar to factory!".

    1. My idea of factory is on a single JVM, if multilple subtypes of a supertype is present and based on client request we are dispatching specific subtype, that's a factory. But Runtime instances are different across OS.

    2. Factory patterns does not talk about static method which are integral part of singleton class. This is a common misconception about factory methods and 'factory method pattern'.

    As per my view Singleton has its merit in controlled no. of instance creation cases. Is there any other alternative when we face with a request where we need system wide single instance. We can use global variable but that will break the encapsulation/abstraction concepts.

    ReplyDelete
  2. Singleton remains a powerful core java pattern and has its place in between Static utility class. as you said classical example is JDK itself which provides both java.lang.Math and java.lang.Runtime differently. Though Singleton seems easy many programmer mess it up when asked write code for Singleton. I have shared few questions as 10 interview question on Singleton pattern in java let me know how do you find it.

    ReplyDelete
  3. The problem with Statics is that they cannot be extended and cannot be injected. The result is that objects that use these statics cannot be easily unit tested; and the system that relies on statics becomes rigid.

    ReplyDelete
  4. Every point here is good, but I find it very interesting that everyone seems to be looking for the perfect solution and is stumping for the tool they like to use the most :) Different situations call for alternative solutions.

    Static class data is designed to be shared between class instances, and it is a good way of managing data that has to be "global" for those instances. Java and C# don't have global data, but C++ and other object-oriented languages do and we should avoid it with static class data.

    Static class methods are effectively stand-alone functions that we are trying to manage in an object-oriented environment. The Math class in Java brought up above is an excellent example of this: where else could we lump together a bunch of similar but technically not cohesive functions except to make them static? Remember, cohesion implies that they work together with the same data. So, if you need to do what was done for Math then static methods are the answer. And of course one way to create a singleton is to use a static method, because the creation has to take place without a class instance.

    But the points the Knetch above and others before him made is very true. The "static factory method" is simpler to use than putting the factory method in a singleton, but smells as an object-oriented solution. A factory method, like everything else we strive to do, should be a method of an instance and not a method of a class.

    Another point of discussion was the singleton as a factory. Design patterns (and these are not "Java patterns" as the principle ones were cataloged before Java was released) are often COMBINED together to accomplish a task. That does not create new patterns, nor does it give existing patterns new responsibilities. Factory methods are often implemented in classes that follow the singleton pattern because that defines a class with a "single responsibility" (R. Martin) to return the class instances.

    The discussion that the Java class Runtime is a singleton is correct, it is. I don't really know or care if any particular JVM returns a subclass of Runtime unique to it. Except that if it actually there is a subclass then I'm interacting with Runtime and it is no longer a singleton. At this point the getRuntime method is technically a STATIC FACTORY METHOD that returns an instance of the appropriate subclass.

    And that last issue brings up the final point that the original statement above that a factory always must return a new instance is unfortunately incorrect (sorry). A factory must always return an APPROPRIATE instance at the time it is used. If anyone feels differently I'm always open to discussion but I did go back and check my copy of the Gang-of-Four and as I recalled it doesn't mention "new instance" in the description of the factory method :)

    ReplyDelete
    Replies
    1. Note to self: Strike the extra word "there" from the third sentence in the second to last paragraph :)

      Delete
    2. Thanks for your thought. Today I was trying to write unit test case for a class which in turn uses a static utility class. And I am stuck. That brought me back to my own blog and to your well thought comment.

      Delete