Design patterns in the test of timeSingleton
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.
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).
More posts in "Design patterns in the test of time" series:
- (21 Jan 2013) Mediator
- (18 Jan 2013) Iterator
- (17 Jan 2013) Interpreter
- (21 Nov 2012) Command, Redux
- (19 Nov 2012) Command
- (16 Nov 2012) Chain of responsibility
- (15 Nov 2012) Proxy
- (14 Nov 2012) Flyweight
- (09 Nov 2012) Façade
- (07 Nov 2012) Decorator
- (05 Nov 2012) Composite
- (02 Nov 2012) Bridge
- (01 Nov 2012) Adapter
- (31 Oct 2012) Singleton
- (29 Oct 2012) Prototype
- (26 Oct 2012) Factory Method
- (25 Oct 2012) Builder
- (24 Oct 2012) A modern alternative to Abstract Factory–filtered dependencies
- (23 Oct 2012) Abstract Factory
Comments
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).
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/
"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.
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.
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.
"per request" -> not "per appdomain" (at least) -> no singleton
// Haiku class Singleton { private Singleton(){} public static readonly Singleton Current = new Singleton(); }
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
@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?
HttpContext.Current and DateTime.Now were given as examples of "hidden dependencies", not singletons..
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.
Can you provide some more detail as to why
DateTime.Now
has hidden dependencies?@James C-S Write a unit test that asserts on the behavior when the date is "yesterday".
A pattern so common and useful as singleton is should be part of the language, as they do in Scala
Comment preview