Singletons – Are they really evil?

So a few weeks back I learned about the Singleton Pattern (this wasn’t the first time I heard of it, I just never really needed it before). I decided to make a tweet – mainly to imprint in my memory, what I learned that week. The response I got was this:

Now this got me thinking: Why would someone invent a pattern, that is inherently evil?

I spent quite a few hours (besides the time I already spent) to read a bunch of articles on the topic. I’ll try to summarize my findings in this post.

Why do some people consider singletons to be an anti-pattern?

I think the best answer to that is: Because they are easy to abuse. Looking at the article from the tweet, quite a few things are mentioned. A lot of these points are repeated in other articles, critical of the Singleton Pattern. Here are some of the points and what I found out about them:

It makes it difficult to write good unit tests

Not if you are using a state-less singleton (i.e. a singleton that does not remember anything about what it has done earlier). If your singleton does have a state, then yes. It will become more difficult to write unit tests. However, singletons shouldn’t be the foundation of your application. They should be rare and singletons with a state should be even rarer. If you find a good use-case for a stateful singleton, you can probably find a good way to test it – or the code that uses it.

It prevents dependency injection

Actually they don’t. You might argue that they make dependency injection irrelevant, since you can always just grab the instance from the singleton itself. Much like you would access a static class. But there is a difference: Singletons can implement an interface (in C# at least), statics cannot – just have a look at this Stack Overflow post. Which means that you can inject the singleton and get some of the advantages from dependency injection, which you will not get if you are using static classes. Again, this is not an argument to always use singleton. Just that it can be used in certain cases.

It introduces a global state

This is probably the best argument against stateful singletons. They do introduce a global state and you should be very aware of this. I have occasionally used this in situation where an object exists, which is logically speaking global – for instance as a controller for automating a PCOMM client (I don’t think a lot of people need this). So if you do make a singleton – and if you do give it a state – you should be painfully aware of what you are doing.

Is the Singleton Pattern ever used in production?

Mostly yes. But then again, if the fact that something is used in production is a valid argument to use it, then you can do all sorts of crap.

It just so happens though, that it is actually used by most people (in the C# world at least), even if they aren’t aware of it. It’s used in a slightly different manner though, which is through the instantiation via dependency injection. Have a look at this code, from the Startup.cs class in the Blazor template:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();
}

The .AddSingleton<T>() exists in most (if not all) dependency injection libraries. There might be some arguing that this is not an actual singleton pattern. And maybe they are right. But even if it is not, to me it proves that the concept of singletons is not to be completely dismissed.

So if you got this far, let me summarize: I believe that there is a case to be made for the Singleton Pattern, in some cases. However, singletons is a special type and as such should only be used in special cases. And if you decide to use it, make sure that you know why you are using it.

If you want to learn more about the Singleton pattern, I would recommend reading this article by Jon Skeet or watch Tim Corey’s YouTube video on the topic.

Published by Jakob Busk Sørensen

Software developer, currently focusing on process automation.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: