Ayende @ Rahien

Refunds available at head office

Design patterns in the test of time: Singleton

In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.

More about this pattern.

I won’t show code or diagrams here. If you don’t know the Singleton pattern, you probably don’t have any business reading this series. Go hit the books and then come back for the rest of my review.

Of the top of my head, I can’t think of a single pattern that has been as denigrated as the Singleton pattern. It has been the bane of testers anywhere, and just about any Singleton implementation had had to become thread safe, given the demands that we usually have from our apps.

That basically means that any time that you use a Singleton, you have to be damn sure that your code is thread safe.  When it isn’t, this becomes really painful. That along would be a huge mark against it, since multi thread proofing code is hard. But Singleton also got a bad rep because they create hidden dependencies that were hard to break. Probably the most famous of them was HttpContext.Current and DateTime.Now.

Singleton may have a tattered reputation and wounded dignity, but it is still a crucially important pattern. Most of the issues that people have with the Singleton aren’t with the notion of the single instance, but with the notion of a global static gateway, which means that it becomes very hard to modify for things like tests, and it is easy to create code that is very brittle in its dependencies on its environment.

Common workaround to that is to break apart the notion of accessing the value and the single nature of the value. So you typically inject the value in, and something else, usually the container, is in charge of managing the lifetime of the object.

Common use cases for Singletons include caches (which would be pretty bad if they didn’t stuck around) and the NHibernate’s Session Factory (which is very expensive to create).

Recommendation: The notion of having just a single instance of an object is still very important, especially when you use that single instance to coordinate things. It does means that you have multi threading issues, but that can be solved. It is a very useful pattern, but you have to watch for the pit falls (global static accessor that is used all over the place is one of the major ones).

Comments

sw
10/31/2012 10:15 AM by
sw

Isn't there a difference between the Singleton Pattern and a singleton lifetime? The pattern is always connected with the global static accessor while the lifetime is something that has to be managed by an external instance (like a di container).

Patrick Smacchia
10/31/2012 12:04 PM by
Patrick Smacchia

Common workaround to that is to break apart the notion of accessing the value and the single nature of the value. So you typically inject the value in, and something else, usually the container, is in charge of managing the lifetime of the object.

I agree 100% with you on that. But static access to singleton object is really part of the DP Singleton in the mind of all developers. So I'd suggest giving a different name like Single Instance Pattern or Manager Pattern to what you describe.

Singleton per-se makes the code highly un-testable. More generally the 'static' keyword should be use with great care, here are my recommendations: http://codebetter.com/patricksmacchia/2009/11/16/back-to-basics-usage-of-static/

dada
10/31/2012 01:28 PM by
dada

"Probably the most famous of them was HttpContext.Current"

HttpContext.Current is not an example of a singleton, just an example of a public static prop.

Jason Smith
10/31/2012 01:50 PM by
Jason Smith

As Patrick alluded, the biggest problem with the Singleton pattern is in how it is misapplied as an access "pattern". If we follow the classification that the GOF gave it, Singleton is a creational pattern. Period. Unfortunately, most folks see a public getInstance() or Current member and think they've found a geek-sanctioned way to implement global variables.

Second, it is an implementation concern. Just like any other implementation concern, that concern shouldn't be exposed to client code. Simply put, the only code that should care something is a singleton, is the singleton itself. Every other piece of code should depend on receiving an actual reference to an instance.

AndersM
10/31/2012 02:50 PM by
AndersM

Dada: Yes, you get the singleton through the static property, but the returned object is still a singleton. There is only one httpcontext per request.

dada
10/31/2012 03:01 PM by
dada

"per request" -> not "per appdomain" (at least) -> no singleton

Starfish
10/31/2012 03:41 PM by
Starfish

// Haiku class Singleton { private Singleton(){} public static readonly Singleton Current = new Singleton(); }

Oded
10/31/2012 03:41 PM by
Oded

DateTime.Now is not a singelton, I would consider it a static property/factory of some sort... You are getting a different instance on every call

Rafal
10/31/2012 05:18 PM by
Rafal

@AndersM One instance per request is not the same as single instance. For example, httprequest.current is not shared by multiple threads... And what about DateTime.Now - where's the singleton?

Tudor
11/01/2012 01:19 PM by
Tudor

HttpContext.Current and DateTime.Now were given as examples of "hidden dependencies", not singletons..

AndersM
11/01/2012 02:13 PM by
AndersM

Rafal: That is a matter of definition. I see nothing wrong in defining it as a singleton in the request-scope. A lot of other people do the same.

James C-S
11/02/2012 01:07 AM by
James C-S

Can you provide some more detail as to why DateTime.Now has hidden dependencies?

kijana.woodard
11/02/2012 03:06 AM by
kijana.woodard

@James C-S Write a unit test that asserts on the behavior when the date is "yesterday".

Dario Iacampo
11/10/2012 01:56 PM by
Dario Iacampo

A pattern so common and useful as singleton is should be part of the language, as they do in Scala

Comments have been closed on this topic.