Problems with Singleton Pattern

What are drawbacks or disadvantages of singleton pattern?

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.

Problems with Singleton Pattern

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.

Why is Singleton considered an anti-pattern?

To help with answering, here is more about the anti-pattern comment:

it is overused, introduces unnecessary restrictions in situations
where a sole instance of a class is not actually required, and
introduces global state into an application

From: http://en.wikipedia.org/wiki/Singleton_pattern

For more on this you can look at: https://www.michaelsafyan.com/tech/design/patterns/singleton

Here is a great ending to the blog above:

In short, the singleton pattern makes code more complex, less useful,
and a real pain to re-use or test. Eliminating singletons can be
tricky, but it’s a worthwhile endeavour.

OK, so, the reason it is an anti-pattern is described well in this paragraph, and, as the author expresses, it tightly couples your code to the singleton.

If you find that you want to use a singleton, you may want to consider your design, but there are times where it is useful.

For example, once I had to write an application that could have at most one database connection, to process thousands of requests. So, a singleton makes sense since I am resource constrained to having only one instance.

But, generally this is used to simplify code, without thinking of the difficulties that will be introduced.

For example, and this applies to static classes also, if you unit test, or have concurrency, then the state of one request will change the state and that may cause problems, as the class calling the instance may be assuming the state is as it expected.

I think the best way to challenge the use is to think of how to handle it if your program is multi-threaded, and a simple way to do that is to unit test it, if you have several tests that run at one time.

If you find that you still need it, then use it, but realize the problems that will be encountered later.

singleton pattern performance drawbacks

An important part of designing big software systems is to minimize the coupling between components and classes. This can be done through the encapsulation of the implementation of different components. The more components know about each other the higher is the dependency between them.

Using the Singleton Pattern means to be coupled to an implementation class (not to an interface, or to an abstraction). It would be better that each component that is using the GameManager would use a GameManagerInterface instead, so that the implementation can be easily changed or extended. Hiding the dependency to the concrete Singleton Class is difficult because somewhere you have to call the static method.

...
IGameManager iGameManager = GameManager.getInstance();
...

Using the Singleton Pattern like this is... :

 GameManager.instance.someOtherClass.someVariable     

... is never a good idea. Doing so would couple the calling class to the implementation of each of the called classes. Its best to only communicate with your direct neighbours as said in the "Law of Demeter"
(a.k.a. "Tell Don't Ask", or "Don't Talk to Strangers").

Maybe for you its time to think about the purpose of the Singleton Pattern: The Singleton Pattern is used to ensure, that there is only one instance of a Class. Nothing more.

Using the static "getInstance" method everywhere in your code leads to hidden dependencies as mentioned before. What you are doing is to use the Singleton Pattern as a replacement for a global variable. This makes your system fragile, because every bit of your code is dependant of the implementation of the singleton class. Changing this class could crash your whole system.

What's wrong when not using singleton pattern

You seem not to understand the concept that this example is trying to explain. ChocolateBoiler is not a real boiler, it's a java class.

However, this class could be used to instruct a piece of hardware (a real boiler controller) to execute some actions. If you mistakenly had two instances of ChocolateBoiler and you mistakenly use both of them to instruct the same boiler controller, then obviously you're in trouble.

There are two 'mistakenly' in my previous paragraph, and you may argue that if you do things 'mistakenly' in general, then you're in trouble anyway. But in case of badly designed singletons, mistakes may not be so obvious. If you serialize and deserialize a singleton that does not handle serialization concerns to keep uniqueness, and then try to use that instance to heat the boiler, you could burn the boiler down.

Issue with singleton pattern in python

You can rewrite your methodC as:

    def methodC(request_proxy_url):
original_proxies = self._soap_client.transport.session.proxies
self._soap_client.transport.session.proxies = {"https": request_proxy_url}
resp = self._soap_client.ServiceE(
body
)
self._soap_client.transport.session.proxies = original_proxies
return resp

(and do similar for any other methods which need to modify the set up of the self._soap_client instance before making the request)

I am a bit skeptical of enforcing the singleton pattern, rather than just creating a global var in a module and importing that from everywhere... but that is just personal taste and no relation to your issue.

Knowing the nature of SOAP APIs I expect the zeep.Client instance is quite a heavy object so it totally makes sense to try to avoid having multiple instances if you can avoid it.

If you use a multi threaded platform (like e.g. Python with gevent) then you have to be careful to avoid global vars which mutate their shared state, like this MySoapClient now does.

An alternative would be for it to maintain a small number of distinct zeep.Client instances, and for each methodA, methodC etc to use the appropriate _soap_client instance. Something like:

class MySoapClient(metaclass=Singleton):
"""MyFancySoapClient"""

def __init__(
self,
user: str = "username",
password: str = "password",
wsdl: str = "wsdl_url_goes_here",
request_proxy_url: str = "default value",
):
self._history = HistoryPlugin()
self._soap_client = zeep.Client(wsdl, plugins=[self._history])
self._soap_client_proxied = zeep.Client(wsdl, plugins=[self._history])
self._soap_client_proxied.transport.session.proxies = {"https": request_proxy_url}

def methodB():
resp = self._soap_client.ServiceB(
body
)
return resp

def methodC(request_proxy_url):
request_proxy_url}
resp = self._soap_client_proxied.ServiceE(
body
)
return resp

# etc

C++ Singleton design pattern

In 2008 I provided a C++98 implementation of the Singleton design pattern that is lazy-evaluated, guaranteed-destruction, not-technically-thread-safe:

Can any one provide me a sample of Singleton in c++?

Here is an updated C++11 implementation of the Singleton design pattern that is lazy-evaluated, correctly-destroyed, and thread-safe.

class S
{
public:
static S& getInstance()
{
static S instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
private:
S() {} // Constructor? (the {} brackets) are needed here.

// C++ 03
// ========
// Don't forget to declare these two. You want to make sure they
// are inaccessible(especially from outside), otherwise, you may accidentally get copies of
// your singleton appearing.
S(S const&); // Don't Implement
void operator=(S const&); // Don't implement

// C++ 11
// =======
// We can use the better technique of deleting the methods
// we don't want.
public:
S(S const&) = delete;
void operator=(S const&) = delete;

// Note: Scott Meyers mentions in his Effective Modern
// C++ book, that deleted functions should generally
// be public as it results in better error messages
// due to the compilers behavior to check accessibility
// before deleted status
};

See this article about when to use a singleton: (not often)

Singleton: How should it be used

See this two article about initialization order and how to cope:

Static variables initialisation order

Finding C++ static initialization order problems

See this article describing lifetimes:

What is the lifetime of a static variable in a C++ function?

See this article that discusses some threading implications to singletons:

Singleton instance declared as static variable of GetInstance method, is it thread-safe?

See this article that explains why double checked locking will not work on C++:

What are all the common undefined behaviours that a C++ programmer should know about?

Dr Dobbs: C++ and The Perils of Double-Checked Locking: Part I

singleton is design-pattern or anti-pattern?

As far as I know, the book AntiPatterns by Brown et al, 1998 may have been the first to popularise the term. It defines an anti-pattern like this:

"An AntiPattern is a literary form that describes a commonly occurring solution to a problem that generates decidedly negative consequences."

I think that it's worthwhile to pay attention to the phrase decidedly negative consequences. Most solutions come with some disadvantages, but in order for a 'solution' to be an anti-pattern, the disadvantages must clearly outweigh any advantages produced.

I usually look at it another way. If I can solve the problem in a different way that generates at least as many advantages, but fewer disadvantages, then the first 'solution' might be an anti-pattern.

As described in the GoF book, the Singleton design pattern addresses a particular problem: Sometimes you want to ensure that only one instance of a class can exist.

This can be appropriate for performance reasons. If the object holds a large amount of data, making sure that only one exists could improve performance.

Even if the object doesn't hold a large amount of memory, you may want to make a small immutable object a Singleton if you otherwise expect that client code might instantiate millions of identical objects.

Particularly when the Singleton object represents immutable data it's hard to argue that it has decidedly negative consequences. It's basically just a constant, like string.Empty. The Singleton pattern is a good solution to that kind of problem.

On the other hand, many people use mutable Singletons as a replacement for techniques like Dependency Injection or partial function application. When used in this way, a Singleton becomes a global variable, which most people nowadays agree should be avoided.

Since Singleton has valid uses, I don't think it can be called an anti-pattern. On the other hand, I'd consider a mutable Singleton a code smell bordering on anti-pattern.

Are Singletons really that bad?

The key thing to remember is that design patterns are just a tool to help you understand the abstract concepts. Once you have that understanding, restricting yourself specifically to a "recipe" from a book is pointless and hurts your ability to write the code most appropriate for your purpose.

That said, reading books like GoF will present you with more ways to think about problems so that when the time comes to implement something on your own, you'll have a wider set of perspectives to approach the problem from.

In your case, if using singleton makes sense in every case, then go right ahead. If it "sort of" fits and you have to implement it in some clunky way, then you need to come up with a new solution. Forcing a pattern that isn't perfect is somewhat like hammering a square peg in a round hole.

Given that you say "this approach has been effective and proven very practical to our circumstances," I think you're doing fine.

Here are some good books:

Gang of Four Book - the classic book for design patterns

Head First Design Patterns - I've heard this recommended by a few people as an alternative

When should the Singleton pattern NOT be used? (Besides the obvious)

Summary Version:

You know how often you use globals? Ok, now use Singletons EVEN LESS. Much less in fact. Almost never. They share all the problems globals have with hidden coupling (directly impacting testability and maintainability), and often the "only one can exist" restriction is actually a mistaken assumption.

Detailed Answer:

The most important thing to realize about a singleton is that it is global state. It is a pattern for exposing a single instance of globally unmitigated access. This has all of the problems in programming which globals have, but also adopts some interesting new implementation details and otherwise very little real value (or, indeed, it may come at an unnecessary extra cost with the single instance aspect). The implementation is different enough that people often mistake it for an object oriented encapsulation method when it is really just a fancy single instance global.

The only situation in which you should consider a singleton is when having more than one instance of already global data would actually be a logical or hardware access error. Even then you should typically not deal with the singleton directly, but instead provide a wrapper interface which is allowed to be instantiated as many times as you need it to be, but only accesses global state. In this manner you can continue to use dependency injection and if you can ever unmarry global state from the behavior of the class it isn't a sweeping change across your system.

There are subtle issues with this, however, when it appears as if you are not relying on global data, but you are. So that (using dependency injection of the interface which wraps the singleton) is only a suggestion and not a rule. In general it is still better because at least you can see that the class relies upon the singleton whereas just using the ::instance() function inside the belly of a class member function hides that dependency. It also allows you to extract classes relying on the global state and make better unit tests for them, and you can pass in mock do-nothing objects where if you bake reliance on the singleton directly into the class this is MUCH more difficult.

When baking a singleton ::instance call which also instantiates itself into a class you make inheritance impossible. Work-arounds typically break the "single instance" part of a singleton. Consider a situation where you have multiple projects relying on shared code in a NetworkManager class. Even if you want this NetworkManager to be global state, and single instance, you should be very skeptical about making it into a singleton. By creating a simple singleton which instantiates itself you are basically making it impossible for any other project to derive from that class.

Many consider the ServiceLocator to be an anti-pattern, however I believe it is a half step better than the Singleton and effectively eclipses the purpose of the Go4 pattern. There are many ways to implement a service locator, but the basic concept is that you break up the construction of the object and the access of the object into two steps. In this way, at runtime, you can connect the appropriate derived service, and then access it from a single global point of contact. This has the benefit of an explicit object construction order, and also allows you to derive from your base object. This is still bad for most of the stated reasons, but it is less bad than the Singleton and is a drop-in replacement.

One specific example of an acceptable singleton(read: servicelocator) may be in wrapping a single-instance c style interface like SDL_mixer. One example of a singleton often naively implemented where it probably shouldn't be is in a logging class (what happens when you want to log to console AND to disk? Or if you want to log subsystems separately.)

The most important problems of relying on global state, however, pretty much always come up when you're trying to implement proper unit testing (and you should be trying to do that). It becomes so much harder to deal with your application when the bowels of classes that you don't really have access to are trying to do unmitigated disk writing and reading, connect to live servers and send real data, or blast sound out of your speakers willy nilly. It's much, MUCH, better to use dependency injection so you can mock up a do-nothing class (and see that you need to do that in the class constructor) in case of a test plan and point it at that without having to divine all the global state your class depends on.

Related Links:

  • Brittleness invoked by Global State and Singletons
  • Dependency Injection to Avoid Singletons
  • Factories and Singletons

Pattern Use vs Emergence

Patterns are useful as ideas and terms, but unfortunately people seem to feel the need to "use" a pattern when really patterns are implemented as need dictates. Often the singleton specifically is shoehorned in simply because it's a commonly discussed pattern. Design your system with an awareness of patterns, but do not design your system specifically to bend to them just because they exist. They are useful conceptual tools, but just as you don't use every tool in the toolbox just because you can, you shouldn't do the same with patterns. Use them as needed and no more or less.

Example Single-Instance Service Locator

#include <iostream>
#include <assert.h>

class Service {
public:
static Service* Instance(){
return _instance;
}
static Service* Connect(){
assert(_instance == nullptr);
_instance = new Service();
}
virtual ~Service(){}

int GetData() const{
return i;
}
protected:
Service(){}
static Service* _instance;
int i = 0;
};

class ServiceDerived : public Service {
public:
static ServiceDerived* Instance(){
return dynamic_cast<ServiceDerived*>(_instance);
}
static ServiceDerived* Connect(){
assert(_instance == nullptr);
_instance = new ServiceDerived();
}
protected:
ServiceDerived(){i = 10;}
};

Service* Service::_instance = nullptr;

int main() {
//Swap which is Connected to test it out.
Service::Connect();
//ServiceDerived::Connect();
std::cout << Service::Instance()->GetData() << "\n" << ((ServiceDerived::Instance())? ServiceDerived::Instance()->GetData() :-1);
return 0;
}


Related Topics



Leave a reply



Submit