views:

8761

answers:

37

The Singleton pattern is a fully paid up member of the GoF Patterns Book but lately seems rather orphaned by the developer world. I still use quite a lot of singletons, especially for Factory classes, and while you have to be a bit careful about multithreading issues (like any class actually) fail to see why they are so awful.

This site especially seems to assume that everyone agrees that Singletons are evil. Why?

+11  A: 

some people consider them stupid :)

s t
You beat me to it!
Mike Stone
Awesome read, thanks. :)
apphacker
+2  A: 

Because they are basically object oriented global variables, you can usually design your classes in such a way so that you don't need them.

Ycros
If you class isn't limited to once instance, you'll need static members in your class managed by semaphores which comes out to pretty much the same thing! What is your proposed alternative?
Jeach
I have a huge application with a "MainScreen" this screen opens up many smaller modal/non modal windows/ UI forms.IMHO I feel that the MainScreen should be a singleton so that for example, a widget somewhere in a far corner of the application wants to show its status in the MainScreen's status bar, all it has to do is MainScreen.getInstance().setStatus("Some Text");What do you propose as an alternative ? Pass MainScreen all over the application ?? :D
Salvin Francis
+10  A: 
  1. It is easily used (abused) as a global variable.
  2. Classes that depend on singletons are relatively harder to unit test in isolation.
jop
+6  A: 

See Wikipedia Singleton_pattern

Extract: "It is also considered an anti-pattern by some people, who feel that it is overly used, introducing unnecessary limitations in situations where a sole instance of a class is not actually required.[1][2][3][4]"

References (only relevant references from the article)

  1. ^ Alex Miller. Patterns I hate #1: Singleton, July 2007
  2. ^ Scott Densmore. Why singletons are evil, May 2004
  3. ^ Steve Yegge. Singletons considered stupid, September 2004
  4. ^ J.B. Rainsberger, IBM. Use your singletons wisely, July 2001
GUI Junkie
Why does this get down-voted? It has a complete and comprehensive description of the Singleton Pattern.
GUI Junkie
A description about the pattern doesn't explain why it is considered as evil...
Jrgns
Hardly fair: "It is also considered an anti-pattern by some people, who feel that it is overly used, introducing unnecessary limitations in situations where a sole instance of a class is not actually required."Look at the references... Anyway there’s RTFM to me.
GUI Junkie
+2  A: 

There is nothing inherently wrong with the pattern, assuming it is being used for some aspect of your model which is truly single.

I believe the backlash is due to its overuse which, in turn, is due to the fact that it's the easiest pattern to understand and implement.

Ben Hoffstein
I think the backlash has more to do with people practicing formalized unit testing realising that they are a nightmare to deal with.
Jim Burger
Not sure why this is at -1. It's not the most descriptive answer but he's not wrong either.
Outlaw Programmer
A: 

To John Millikin:
They're helpful when you mix pieces of code. It's good for each piece of code to have it's "global" variables kept in it's own place so if you have two pieces of code, one using the global variable DB for connecting to the database and the other one using DB as an integer or something meaning "data baud" they won't get mixed up.
They help a bit because you know your global stuff has it's own place but otherwise, I have to agree with you: they're globals with a fresh coat of paint.

+36  A: 

Misko Hevery, from Google, has some interesting articles on exactly this topic...

Singletons are Pathological Liars

Where have all the Singletons Gone

jason
Misko's articles on the subject are the best thing going around on it at the moment.
Chris Mayer
The first link doesn't actually address a problem with singletons, but rather assuming a static dependency inside the class. It's possible to fix the given example by passing in parameters, yet still use singletons.
DGM
@DGM: Exactly - in fact, there is a huge logical disconnect between the 'rationale' part of the article, and the 'Singletons are the cause' part.
Harper Shelby
A: 

Singletons are simply a new way to use global variables. Just like any other tool, when you over use singletons, it can lead to a poorly constructed, and possibly tightly coupled, code base.

Singletons used to be a good way to eek out some performance out of your app since you only instantiate an object once.

casademora
-1 from me because I don't think performance is ever a consideration for using a Singleton. After all, you could "just create one" and would have the same memory usage without the global reference.
Outlaw Programmer
I never consider performance either. However, I have heard of some who think it does have some performance benefit, which is why I mentioned it.
casademora
I really don't see how there could possibly be a performance benefit.
ColinD
Instance of Peformance benefit of singletons: You need to load a lot of data to init an object properly. Rather than go through the logic and IO on every creation, you can create a singleton in conjunction with the protoype pattern to clone this object (if true instances are needed).
casademora
A: 

It blurs the separation of concern.

Supposed that you have a singleton, you can call this instance from anyway inside your class. Your class is no longer as pure as it should be. Your class will now no longer operate on its members and the members that it receives explicitly. This will create confusion because the users of the class don't know what is the sufficient information the class needs. The whole idea of encapsulation is to hide the how of a method from the users, but if inside the method a singleton is used, one will have to know the state of the singleton in order to use the method correctly. This is anti-OOP.

Ngu Soon Hui
Not quite sure about this answer. The same could be said for any object really. The real problem is that a Singleton can be accessed from ANYWHERE. A clean API and sufficient documentation can keep clients from using it incorrectly.
Outlaw Programmer
A: 

It's easy to make a memory leak with a singleton, even if you have gc.

Vasil
can you elaborate?
Robert Paulson
If you have a garbage collector, the Singleton won't be reclaimed until the class is unloaded. For all intents and purposes, I think a Singleton is expected to live for the duration of the program.
Outlaw Programmer
+19  A: 

A singleton gets implemented using a static method. Static methods are avoided by people who do unit testing because they cannot be mocked or stubbed. Most people on this site are big proponents of unit testing. The generally most accepted convention to avoid them is using the inversion of control pattern.

jwanagel
+33  A: 

Some coding snobs look down on them as just a glorified global. In the same way that many people hate the goto statement there are others that hate the idea of ever using a global. I have seen several developers go to extraordinary lengths to avoid a global because they considered using one as an admission of failure. Strange but true.

In practice the Singleton pattern is just a programming technique that is a useful part of your toolkit of concepts. From time to time you might find it is the ideal solution and so use it. But using it just so you can boast about using a design pattern is just as stupid as refusing to ever use it because it is just a global.

Phil Wright
The failure I see in Singleton is that folks use them instead of globals because they're somehow "better." The problem is (as I see it), that the things that Singleton brings to the table in these cases are irrelevant. (Construct-on-first-use is trivial to implement in a non-singleton, for example, even if it's not actually using the constructor to do it.)
dash-tom-bang
Being global is the least of its problems. As @dash-tom-bang says, if you want a global, use a global. Replacing it with a singleton is just stupid.
jalf
+100  A: 

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 app. 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.

Jim Burger
I disagree with you. Since comments are allowed only 600 chars, I have written a Blog Post to comment on this, please see the link below.http://jorudolph.wordpress.com/2009/11/22/singleton-considerations/
Johannes Rudolph
On point 1 and 4, I think singletons are useful, and in fact almost perfect for caching data (especially from a DB). The increase in performance far outway the complexities involved in modeling unit tests.
Dai Bok
@Dai Bok: "caching data (especially from a DB)" use the proxy pattern to do this...
ceretullis
ok, I will look into that.
Dai Bok
Ok, just looked into it, the problem is particulaly with web apps is that that if the proxy gets out scope (garbage collected or something), this cache memory may be deallocated? I may ask a stupid question next.
Dai Bok
I don't agree with any of the points made above! Singletons are perfectly fine and justified in good designs and architectures! There are just a few things to remember: 1) Don't overuse them (we have a tendency to create too many and in places that it was not necessary). 2) Don't create a bunch of static methods (that will cause issues indicated by your point 3). 3) Interface them rather than just a class which will help alleviate your points 1 and 3. Interfacing them also helps keep my point 2 valid.
Jeach
@Jeach - further disagreement: static methods are very simple to test. You call them with parameters to find out what they do. What matters is that they are pure functions without side-effects, so you can detect their behaviour by looking only at their declared outputs. Static methods may take other functions (or interfaces) as arguments, so they can have all their dependent functionality "injected" into them. Hence a static method by itself is not a problem. Depending on your ideology, you might think any direct call to a static method is a problem... (cont.)
Daniel Earwicker
Some insist that a unit test must not call any other parts of the program, so a static method must never call any other static method directly in order to be independently testable, but that is crazy. You need to write a unit test for each method to test the behaviour of that method; however it is internally implemented, nothing stops you doing this. And if a method A passes its test, then it is a tested component, and hence you can use it from method B, and if B fails, you know it's not because of A because A passed. Or if A fails, you know to look there for a problem first, then retest.
Daniel Earwicker
Wow, great responses. I probably used overly agressive wording here, so please keep in mind I was answering a negatively geared question. My answer was meant to be a short list of the 'anti patterns' that occur from bad Singleton usage. Full disclosure; I too use Singletons from time to time. There are more neutrally posed questions on SO that would make excellent forums for when Singletons can be considered a good idea. For instance, http://stackoverflow.com/questions/228164/on-design-patterns-when-to-use-the-singleton
Jim Burger
Bad opinions on Singletons are a result of OO. Static/global data still has its place, just not wrapped in metanonsense.
Matt Joiner
@Matt fair point indeed, some languages tackle this issue better than others. Certainly the rhetoric around Singletons of late focus on the class oriented and object oriented languages.
Jim Burger
A: 

A pattern emerges when several people (or teams) arrives at similar or identical solutions. A lot of people still use singletons in their original form or using factory templates (good discussion in Alexandrescu's Modern C++ Design). Concurrency and difficulty in managing the lifetime of the object are the main obstacles, with the former easily managed as you suggest.

Like all choices, Singleton has its fair share of ups and downs. I think they can be used in moderation, especially for objects that survive the application life span. The fact that they resemble (and probably are) globals have presumably set off the purists.

+18  A: 

One rather bad thing about singletons is that you can't extend them very easily. You basically have to build in some kind of decorator pattern or some such thing if you want to change their behavior. Also, if one day you want to have multiple ways of doing that one thing, it can be rather painful to change, depending on how you lay out your code.

One thing to note, if you DO use singletons, try to pass them in to whoever needs them rather than have them access it directly... otherwise if you ever choose to have multiple ways of doing the thing that singleton does, it will be rather difficult to change as each class embeds a dependency if it accesses the singleton directly.

So basically:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

rather than:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

I believe this sort of pattern is called dependency injection, and is generally considered a good thing.

Like any pattern though... think about it and consider if its use in the given situation is inappropriate or not... rules are made to be broken usually, and Patterns should not be applied willy nilly without thought.

Mike Stone
+4  A: 

When you write code using singletons, say, a logger or a database connection, and afterwards you discover you need more than one log or more than one database, you’re in trouble.

Singletons make it very hard to move from them to regular objects.

Also, it’s too easy to write a non-thread-safe singleton.

Rather than using singletons, you should pass all the needed utility objects from function to function. That can be simplified if you wrap all them into a helper object, like this:

void some_class::some_function(parameters, service_provider& srv)
{
    srv.get<error_logger>().log("Hi there!");
    this->another_function(some_other_parameters, srv);
}
Roman Odaisky
A: 

The following article is a good read about why Singleton is regarded an anti-pattern. The article also discusses two alternatives design approaches for replacing Singleton.

Link to article: SINGLETON - the anti-pattern! by Mark Radford (Overload Journal #57 - Oct 2003)

Frank Grimm
Frank The link doesn't appear to work?
tdyen
tdyen, sorry for late reply! The link works fine for me (just tried it with Opera and Firefox)...
Frank Grimm
+1  A: 

Off the top of my head:

  1. They enforce tight-coupling. If your singleton resides on a different assembly than its user, the using assembly cannot ever function without the assembly containing the singleton.
  2. They allow for circular dependencies, e.g., Assembly A can have a singleton with a dependency on Assembly B, and Assembly B can use Assembly A's singleton. All without breaking the compiler.
Jon Limjap
+16  A: 

The singleton pattern is not a problem in itself. The problem is that the pattern is often used by people developing software with object oriented tools without having a solid grasp of OO concepts. When singletons are introduced in this context they tend to grow into unmanageable classes that contain helper methods for every little use.

Singletons are also a problem from a testing perspective. They tend to make isolated unit-tests difficult to write. Inversion of Control and Dependency Injection are patterns meant to overcome this problem in an object oriented manner that lends itself to unit testing.

In a garbage collected environment singletons can quickly become an issue with regard to memory management.

There is also the multi-threaded scenario where singletons can become a bottleneck as well as a synchronization issue.

Kimoz
A: 

Gilad Bracha has a good article about why "static" is bad, and what he says for static goes double for Singletons. His language NewSpeak has done away with static alltogether!

Lars Westergren
+7  A: 

I'm not going to comment on the good/evil argument, but I haven't used them since Spring (http://springframework.org/) came along. Using dependency injection has pretty much removed my requirements for singleton, servicelocators and factories. I find this a much more productive and clean environment, at least for the type of work I do (java based web applications).

prule
aren't Spring beans, by default, Singletons?
slim
Yeah, but I mean 'coding' singletons. I haven't 'written a singleton' (i.e. with a private constructor yada yada yada as per design pattern) - but yes, with spring I am using a single instance.
prule
+3  A: 

Too many people put objects which are not thread safe in a singleton pattern. I've seen examples of a DataContext (LINQ to SQL) done in a Singleton pattern, despite the fact that the DataContext is not thread safe and is purely a unit-of-work object

Slace
+5  A: 

Singleton is a pattern and can be used or abused just like any other tool.
Bad part of a Singleton is generally the user (or should I say the inappropriate use of a Singleton for things it is not designed to do). The biggest offender is using a Singleton as a fake global variable.

Martin York
+12  A: 

I think the confusion is caused by the fact that people don't know the real application of the Singleton pattern. I can't stress this enough. Singleton is not a pattern to wrap globals. Singleton pattern should only be used to guarantee that one and only one instance of a given class exists during run time.

People think Singleton is evil because they are using it for globals. It is because of this confusion that Singleton is looked down upon. Please, don't confuse Singletons and globals. If used for the purpose it was intended for, you will gain extreme benefits from the Singleton pattern.

Cem Catikkas
+47  A: 

Singletons solve one (and only one) problem.

Resource Contention.

If you have some resource that (1) can only have a single instance, and (2) you need to manage that single instance, you need a Singleton.

There aren't many examples. A log file is the big one. You don't want to just abandon a single log file. You want to flush, sync and close it properly. This is an example of a single shared resource that has to be managed.

It's rare that you need a Singleton. The reason they're bad is that they feel like a Global and they're a fully paid up member of the GoF Patterns Book.

When you think you need a Global, you're probably making a terrible design mistake.

S.Lott
Hardware is also an example right? Embedded systems have lots of hardware that might use singletons - or maybe one big one? <grin>
Jeff
Totally agree. There's a lot of determined "this practice is bad" talk floating around without any recognition that the practice may have its place. Often, the practice is only "bad" because it's frequently misused. There's nothing inherently wrong with the Singleton pattern as long as it's applied appropriately.
Damovisa
Real, by-principle singletons are very rare (and a printer queue certainly isn't one, and neither is a log file - see log4j). More often than not, hardware is a singleton by coincidence rather than by principle. All hardware connected to a PC is at best a coincidental singleton (think multiple monitors, mice, printers, sound cards). Even a 500 mio $ particle detector is a singleton by coincidence and budget constraints - which don't apply in software, thus: no singleton. In telecommunications, neither phone number nor the physical phone are singletons (think ISDN, call center).
digitalarbeiter
Hardware may have only one instance of a variety of resources, but hardware isn't software. There's no reason that a single serial port on a development board should be modeled as a Singleton. Indeed, modeling it so will only make it harder to port to the new board that has two ports!
dash-tom-bang
The single serial port **is** a Singleton. Only one. Multiple instances must be absolutely forbidden. When you move to a board with exactly two ports you have a complex problem, but it amounts to "two Singletons" since you have absolutely limited resources: two ports.
S.Lott
So you'd write two identical classes, duplicating a lot of code, just so you can have two singletons representing two ports?How about just using two global SerialPort objects? How about not modelling the hardware as classes at all? And why would you use singletons, which also imply global access? Do you want *every* function in your code to be able to access the serial port?
jalf
Two serial ports violates the **Singleton** principle. Now there are as many instances as you have hardware, which is not a **Singleton**. It's just a class bound to hardware.
S.Lott
To enforce a rule that only one instance at a time can exist is not the same as _needing_ a singlton. Most DI-framework support single creation which gives you all the benifits of testability and enforces one instance.
Rune FS
@Rune FS. You only *need* a Singleton when you have the situation that only one instance can exist at a time.
S.Lott
@S.Lott I disagree on the _need_ part. a singleton is a solution to that problem but not the _only_ solution to that problem and since singletons easily cause testability and coupling issues I'd say it's a poor solution even to the problem it was designed to solve. There's at most a _can use_ but there no _need_
Rune FS
@Rune FS: I think you might be confusing cause and effect, necessary and sufficient. Singleton design is not equivalent to "only one instance can exist". Singleton does not always follow from "only one instance can exist", since -- as you say -- there may be alternatives. However, "only one instance can exist" is *necessary* for Singleton designs, since no other purpose can possibly exist for Singleton. "only one instance can exist" is not *sufficient* for Singleton design, since there are alternatives.
S.Lott
@S.Lott: Well let me be very specific then because it seems I've been unclear my original comment could have been: "If you have some resource that (1) can only have a single instance, and (2) you need to manage that single instance, you need a Singleton." is a falsum since you can solve that problem with out a singleton so there's no _need_ for a singleton as you put it
Rune FS
@Rune FS: There is a need. But it isn not **sufficient** reason to use a singleton. It's necessary, but not -- as you point out -- sufficient. Need == Necessity. Necessity != Sufficiency.
S.Lott
There's no need because you can get by without so the singleton isn't necessary. It never is but a lot of developers seems to think they need a singleton when actually they don't. Which is my point in stressing that they are neither needed nor nesecarry
Rune FS
+2  A: 

Recent article on this subject by Chris Reath at Coding Without Comments: Singleton I love you but you're bringing me down

David
+1  A: 

Some counterpoints from the author:

You are stuck if you need to make the class not single in the future Not at all - I was in this situation with a single database connection singleton that I wanted to turn into a connection pool. Remember that every singleton is accessed through a standard method:

MyClass.instance

This is similar to the signature of a factory method. All I did was update the instance method to return the next connection from the pool - no other changes required. That would have been far harder if we had NOT been using a singleton.

Singletons are just fancy globals Can't argue with that but so are all static fields and methods - anything that is accessed from the class rather than an instance is essentially global and I dont see so much pushback on the use of static fields?

Not saying that Singletons are good, just pushing back at some of the 'conventional wisdom' here.

Ewan Makepeace
+1  A: 

The problems with Singletons is the issue of increased scope and therefore coupling. There is no denying that there are some of situations where you do need access to a single instance and it can be accomplished other ways.

I now prefer to design around an IOC container and allow the the lifetimes to be controlled by the container. This gives you the benefit of the classes that depend on the instance to be unaware of the fact that there is a single instance. The lifetime of the Singleton cam be changed in the future. Once such example I encountered recently was an easy adjustment from single threaded to multi-threaded.

FWIW, if it a PIA when you try to unit test it then it's going to PIA when you try to debug, bug fix or enhance it.

Mark Lindell
A: 

excellent video on the dangers of singletons http://www.youtube.com/watch?v=-FRm3VPhseI

Chad Grant
+1  A: 

Firstly a class and its collaborators should firstly perform their intended purpose rather than focusing on deoendents. Lifecycle management (when instances are creared snd when they go out of scope) should not be part of the cladses responsibility. The accepted best practice for this is to craft or configure a new component to manage dependencies using dependency injection.

Often software gets more complicated it makes sense to have multiple independent instances of the "singleton" class with different state. Committing code to simply grab the singleton is wrong in such cases. Using Singleton.getInstance() might be ok for small simple systems but it doesn't work / scale when one might need a different instance of the same class.

No class should be thought of as a singleton but rather that should be an aplication of it's usage or how it is used to configure dependents. For a quick and nasty this does not matter- just luke hardcoding say file paths does not matter but for bigger applications such dependencies need to be factored out and managed in more appropriate way using DI.

The problems that singleton cause in testing is a symptom of their hard coded single usage case/environment. The test suite and the many tests are each individual and separate something that is not compatible with hardcoding a singleton.

mP
+1  A: 

This is what I think is missing from the answers so far:

If you need one instance of this object per process address space (and you are as confident as you can be that this requirement will not change), you should make it a singleton.

Otherwise, it's not a singleton.

This is a very odd requirement, hardly ever of interest to the user. Processes and address space isolation are an implementation detail. They only impact on the user when they want to stop your application using kill or Task Manager.

Apart from building a caching system, there aren't that many reasons why you'd be so certain that there should only be on instance of something per process. How about a logging system? Might be better for that to be per-thread or more fine-grained so you can trace the origin of messages more automatically. How about the application's main window? It depends; maybe you'll want all the user's documents to be managed by the same process for some reason, in which case there would be multiple "main windows" in that process.

Daniel Earwicker
A: 

I'm amazed at the Singleton hate. In the Flash world, Singletons are almost a fact of life because of the nature of the SWF/MovieClip architecture. The Flex framework is loaded with singletons, factories, and managers.

Jasconius
+2  A: 

Vince Huston has these criteria, which seem reasonable to me:

Singleton should be considered only if all three of the following criteria are satisfied:

  • Ownership of the single instance cannot be reasonably assigned
  • Lazy initialization is desirable
  • Global access is not otherwise provided for

If ownership of the single instance, when and how initialization occurs, and global access are not issues, Singleton is not sufficiently interesting.

js
A: 

I'd like to address the 4 points in the accepted answer, hopefully someone can explain why I'm wrong.

  1. Why is hiding dependencies in your code bad? There are already dozens of hidden dependencies (C runtime calls, OS API calls, global function calls), and singleton dependencies are easy to find (search for instance()).

    "Making something global to avoid passing it around is a code smell." Why isn't passing something around to avoid making it a singleton a code smell?

    If you're passing an object through 10 functions in a call stack just to avoid a singleton, is that so great?

  2. Single Responsibility Principle: I think this is a bit vague and depends on your definition of responsibility. A relevant question would be, why does adding this specific "responsibility" to a class matter?

  3. Why does passing an object to a class make it more tightly coupled than using that object as a singleton from within the class?

  4. Why does it change how long the state lasts? Singletons can be created or destroyed manually, so the control is still there, and you can make the lifetime the same as a non-singleton object's lifetime would be.

Regarding unit tests:

  • not all classes need to be unit tested
  • not all classes that need to be unit tested need to change the implementation of the singleton
  • if they do need be unit tested and do need to change the implementation, it's easy to change a class from using a singleton to having the singleton passed to it via dependency injection.
Jon
A: 

Here is one more thing about singletons which nobody said yet.

In most cases "singletonity" is a detail of implementation for some class rather than characteristic of its interface. Inversion of Control Container may hide this characteristic from class users; you just need to mark your class as a singleton (with @Singleton annotation in Java for example) and that's it; IoCC will do the rest. You don't need to provide global access to your singleton instance because the access is already managed by IoCC. Thus there is nothing wrong with IoC Singletons.

GoF Singletons in opposite to IoC Singletons are supposed to expose "singletonity" in the interface through getInstance() method, and so that they suffer from everything said above.

Volodymyr Frolov
+1  A: 

Singletons are NOT bad. It's only bad when you make something globally unique that isn't globally unique.

However, there are "application scope services" (think about a messaging system that makes components interact) - this CALLS for a singleton, a "MessageQueue" - class that has a method "SendMessage(...)".

You can then do the following from all over the place:

MessageQueue.Current.SendMessage(new MailArrivedMessage(...));

And, of course, do:

MessageQueue.Current.RegisterReceiver(this);

in classes that implement IMessageReceiver.

StormianRootSolver
A: 

Monopoly is the devil and singletons with non-readonly/mutable state are the 'real' problem...

After reading [Singletons are Pathological Liars][1] as suggested in jason's answer I came across this little tidbit that provides the best presented example of how singletions are often misused.

Global is bad because:

  • a. It causes namespace conflict
  • b. It exposes the state in a unwarranted fashion

When it comes to Singletons

  • a. The explicit OO way of calling them, prevents the conflicts, so point a. is not an issue
  • b. Singletons without state are (like factories) are not a problem. Singletons with state can again fall in two categories, those which are immutable or write once and read many (config/property files). These are not bad. Mutable Singletons, which are kind of reference holders are the ones which you are speaking of.

In the last statement he's referring to the blog's concept of 'singletons are liars'.

How does this apply to Monopoly?

To start a game of monopoly, first:

  • we establish the rules first so everybody is on the same page
  • everybody is given an equal start at the beginning of the game
  • only one set of rules is presented to avoid confusion
  • the rules aren't allowed to change throughout the game

Now, for anybody who hasn't really played monopoly, these standards are ideal at best. A defeat in monopoly is hard to swallow because, monopoly is about money, if you lose you have to painstakingly watch the rest of the players finish the game, and losses are usually swift and crushing. So, the rules usually get twisted at some point to serve the self-interest of some of the players at the expense of the others.

So you're playing monopoly with friends Bob, Joe, and Ed. You're swiftly building your empire and consuming market share at an exponential rate. Your opponents are weakening and you start to smell blood (figuratively). Your buddy Bob put all of his money into gridlocking as many low-value properties as possible but his isn't receiving a high return on investment the way he expected. Bob, as a stroke of bad luck, lands on your Boardwalk and is excised from the game.

Now the game goes from friendly dice-rolling to serious business. Bob has been made the example of failure and Joe and Ed don't want to end up like 'that guy'. So, being the leading player you, all of a sudden, become the enemy. Joe and Ed start practicing under-the-table trades, behind-the-back money injections, undervalued house-swapping and generally anything to weaken you as a player until one of them rises to the top.

Then, instead of one of them winning, the process starts all over. All of a sudden, a finite set of rules becomes a moving target and the game degenerates into the type of social interactions that would make up the foundation of every high-rated reality TV show since Survivor. Why, because the rules are changing and there's no consensus on how/why/what they're supposed to represent, and more importantly, there's no one person making the decisions. Every player in the game, at that point, is making his/her own rules and chaos ensues until two of the players are too tired to keep up the charade and slowly give up.

So, if a rulebook for a game accurately represented a singleton, the monopoly rulebook would be an example of abuse.

How does this apply to programming?

Aside from all of the obvious thread-safety and synchronization issues that mutable singletons present... If you have one set of data, that is capable of being read/manipulated by multiple different sources concurrently and exists during the lifetime of the application execution, it's probably a good time to step back and ask "am I using the right type of data structure here".

Personally, I have seen a programmer abuse a singleton by using it as some sort of twisted cross-thread database store within an application. Having worked on the code directly, I can attest that it was a slow (because of all the thread locks needed to make it thread-safe) and a nightmare to work on (because of the unpredictable/intermittent nature of synchronization bugs), and nearly impossible to test under 'production' conditions. Sure, a system could have been developed using polling/signaling to overcome some of the performance issues but that wouldn't solve the issues with testing and, why bother when a 'real' database can already accomplish the same functionality in a much more robust/scalable manner.

A Singleton is only an option if you need what a singleton provides. A write-one read-only instance of an object. That same rule should cascade to the object's properties/members as well.

Evan Plaice