What are the drawbacks or disadvantages of the singleton pattern? [Answered]

Query explained:

The singleton pattern is a fully paid-up member of the GoF‘s patterns book, but it lately seems rather orphaned by the developer world. I still use quite a lot of singletons, especially for factory classes, and while you have to be a bit careful about multithreading issues (like any class actually), I fail to see why they are so awful.

Dev community on SO especially seems to assume that everyone agrees that Singletons are evil. Why?

What are drawbacks or disadvantages of singleton pattern? Answer #1:

Paraphrased from Brian Button:

  1. They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.
  2. They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.
  3. They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.
  4. They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

Answer #2:

Singletons solve one (and only one) problem.

Resource Contention.

If you have some resources that

(1) can only have a single instance, and

(2) you need to manage that single instance,

you need a singleton.

There aren’t many examples. A log file is the big one. You don’t want to just abandon a single log file. You want to flush, sync and close it properly. This is an example of a single shared resource that has to be managed.

It’s rare that you need a singleton. The reason they’re bad is that they feel like a global and they’re a fully paid up member of the GoF Design Patterns book.

When you think you need a global, you’re probably making a terrible design mistake.

Answer #3:

Some coding snobs look down on them as just a glorified global. In the same way that many people hate the goto statement, there are others that hate the idea of ever using a global. I have seen several developers go to extraordinary lengths to avoid a global because they considered using one as an admission of failure. Strange but true.

In practice the Singleton pattern is just a programming technique that is a useful part of your toolkit of concepts. From time to time you might find it is the ideal solution and so use it. But using it just so you can boast about using a design pattern is just as stupid as refusing to ever use it because it is just a global.

Answer #4:

Misko Hevery, from Google, has some interesting articles on exactly this topic…

Singletons are Pathological Liars has a unit testing example that illustrates how singletons can make it difficult to figure out dependency chains and start or test an application. It is a fairly extreme example of abuse, but the point that he makes is still valid:

Singletons are nothing more than global state. Global state makes it so your objects can secretly get hold of things which are not declared in their APIs, and, as a result, Singletons make your APIs into pathological liars.

Where have all the Singletons Gone makes the point that dependency injection has made it easy to get instances to constructors that require them, which alleviates the underlying need behind the bad, global Singletons decried in the first article.

Answer #5:

I think the confusion is caused by the fact that people don’t know the real application of the Singleton pattern. I can’t stress this enough. Singleton is not a pattern to wrap globals. Singleton pattern should only be used to guarantee that one and only one instance of a given class exists during run time.

People think Singleton is evil because they are using it for globals. It is because of this confusion that Singleton is looked down upon. Please, don’t confuse Singletons and globals. If used for the purpose it was intended for, you will gain extreme benefits from the Singleton pattern.

Answer #6:

One rather bad thing about singletons is that you can’t extend them very easily. You basically have to build in some kind of decorator pattern or some such thing if you want to change their behavior. Also, if one day you want to have multiple ways of doing that one thing, it can be rather painful to change, depending on how you lay out your code.

One thing to note, if you DO use singletons, try to pass them in to whoever needs them rather than have them access it directly… Otherwise if you ever choose to have multiple ways of doing the thing that singleton does, it will be rather difficult to change as each class embeds a dependency if it accesses the singleton directly.

So basically:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

rather than:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

I believe this sort of pattern is called dependency injection and is generally considered a good thing.

Like any pattern though… Think about it and consider if its use in the given situation is inappropriate or not… Rules are made to be broken usually, and patterns should not be applied willy nilly without thought.

The singleton pattern is not a problem in itself. The problem is that the pattern is often used by people developing software with object-oriented tools without having a solid grasp of OO concepts. When singletons are introduced in this context they tend to grow into unmanageable classes that contain helper methods for every little use.

Singletons are also a problem from a testing perspective. They tend to make isolated unit-tests difficult to write. Inversion of control (IoC) and dependency injection are patterns meant to overcome this problem in an object-oriented manner that lends itself to unit testing.

In a garbage-collected environment, singletons can quickly become an issue with regard to memory management.

There is also the multi-threaded scenario where singletons can become a bottleneck as well as a synchronization issue.

Answer #7:

Singletons are also bad when it comes to clustering. Because then, you do not have “exactly one singleton” in your application anymore.

Consider the following situation: As a developer, you have to create a web application which accesses a database. To ensure that concurrent database calls do not conflict each other, you create a thread-save SingletonDao:

public class SingletonDao {
    // songleton's static variable and getInstance() method etc. omitted
    public void writeXYZ(...){
        synchronized(...){
            // some database writing operations...
        }
    }
}

So you are sure that only one singleton in your application exists and all database go through this one and only SingletonDao. Your production environment now looks like this: Single Singleton

Everything is fine so far.

Now, consider you want to set up multiple instances of your web application in a cluster. Now, you suddenly have something like this:

Many singletons

That sounds weird, but now you have many singletons in your application. And that is exactly what a singleton is not supposed to be: Having many objects of it. This is especially bad if you, as shown in this example, want to make synchronized calls to a database.

Of course, this is an example of a bad usage of a singleton. But the message of this example is: You can not rely that there is exactly one instance of a singleton in your application – especially when it comes to clustering.

Hope you learned something from this post.

Follow Programming Articles for more!

About ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ

Linux and Python enthusiast, in love with open source since 2014, Writer at programming-articles.com, India.

View all posts by ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ →