Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with Singleton Pattern

I've been reading about Singleton pattern for last few days. The general perception is that the scenarios where it is required are quite few (if not rare) probably because it has its own set of problems such as

  • In a garbage collection environment it can be an issue with regards to memory management.
  • In a multithreaded environment it can cause bottlenecks and introduce synchronization problems.
  • Headache from testing prespective.

I'm starting to get the ideas behind these issues but not totally sure about these concerns. Like in case of garbage collection issue, usage of static in singleton implementation (which is inherent to the pattern), is that the concern? Since it would mean that the static instance will last till the application. Is it something that degrades memory management (it just means that the memory allocated to the singleton pattern won't be freed)?

Ofcourse in a multithreaded setup, having all the threads being in contention for the singleton instance would be a bottleneck. But how does usage of this pattern causes synchronization problems (surely we can use a mutex or something like that to synchronize access).

From a (unit?)testing perspective, since singletons use static methods (which are difficult to be mocked or stubbed) they can cause problems. Not sure about this. Can someone please elaborate on this testing concern?

Thanks.

like image 830
TL36 Avatar asked Sep 08 '09 06:09

TL36


People also ask

What are the problems with singleton pattern?

Disadvantages of a Singleton PatternUnit testing is more difficult (because it introduces a global state into an application). This pattern reduces the potential for parallelism within a program, because to access the singleton in a multi-threaded system, an object must be serialized (by locking).

What is one of the most common mistakes you can make when implementing a singleton?

A common mistake with that implementation is to neglect synchronization, which can lead to multiple instances of the singleton class.

Are singletons a bad design pattern?

It's not that singletons themselves are bad but the GoF design pattern is. The only really argument that is valid is that the GoF design pattern doesn't lend itself in regards to testing, especially if tests are run in parallel. Using a single instance of an class is a valid construct as long as you apply the following means in code:

What is the singleton pattern in Java?

The singleton pattern is a design pattern that restricts the instantiation of a class to one object. Let’s see various design options for implementing such a class.

Is Singleton an anti-pattern?

Singleton, one of the most popular design patterns has a lot of serious drawbacks and some even consider it an anti-pattern. What are the pitfalls of the famous pattern? What is Singleton? Singleton, one of the original GoF patterns, is probably one of the most famous design patterns out there. Its intent is simple:

How does the singleton pattern violate single responsibility principle?

The Singleton pattern solves two problems at the same time, violating the Single Responsibility Principle: Ensure that a class has just a single instance. Why would anyone want to control how many instances a class has? The most common reason for this is to control access to some shared resource—for example, a database or a file.


1 Answers

In a garbage collection environment it can be an issue with regards to memory management

In typical singleton implementations, once you create the singleton you can never destroy it. This non-destructive nature is sometimes acceptable when the singleton is small. However, if the singleton is massive, then you are unnecessarily using more memory than you should.

This is a bigger issue in languages where you have a garbage collector (like Java, Python, etc) because the garbage collector will always believe that the singleton is necessary. In C++, you can cheat by delete-ing the pointer. However, this opens its own can of worms because it's supposed to be a singleton, but by deleting it, you are making it possible to create a second one.

In most cases, this over-use of memory does not degrade memory performance, but it can be considered the same as a memory leak. With a large singleton, you are wasting memory on your user's computer or device. (You can run into memory fragmentation if you allocate a huge singleton, but this is usually a non-concern).

In a multithreaded environment it can cause bottlenecks and introduce synchronization problems.

If every thread is accessing the same object and you are using a mutex, each thread must wait until another has unlocked the singleton. And if the threads depend greatly upon the singleton, then you will degrade performance to a single-thread environment because a thread spends most of its life waiting.

However, if your application domain allows it, you can create one object for each thread -- this way the thread does not spend time waiting and instead does the work.

Headache from testing prespective.

Notably, a singleton's constructor can only be tested once. You have to create an entirely new test suite in order to test the constructor again. This is fine if your constructor doesn't take any parameters, but once you accept a paremeter you can no longer effective unit teest.

Further, you can't stub out the singleton as effectively and your use of mock objects becomes difficult to use (there are ways around this, but it's more trouble than it's worth). Keep reading for more on this...

(And it leads to a bad design, too!)

Singletons are also a sign of a poor design. Some programmers want to make their database class a singleton. "Our application will never use two databases," they typically think. But, there will come a time when it may make sense to use two databases, or unit testing you will want to use two different SQLite databases. If you used a singleton, you will have to make some serious changes to your application. But if you used regular objects from the start, you can take advantage of OOP to get your task done efficiently and on-time.

Most cases of singleton's are the result of the programmer being lazy. They do not wish to pass around an object (eg, database object) to a bunch of methods, so they create a singleton that each method uses as an implicit parameter. But, this approach bites for the reasons above.

Try to never use a singleton, if you can. Although they may seem like a good approach from the start, it usually always leads to poor design and hard to maintain code down the line.

like image 152
carl Avatar answered Sep 20 '22 01:09

carl