Singletons: Solving problems you didn’t know you never had since 1995

Funny how some sub­jects seem to attract catchy titles like flies. A lot of very clever peo­ple have writ­ten vol­umes about “The Sim­ple­ton Pat­tern”, and “Sin­gle­toni­tis” (bah, dead link, let’s use this instead then).

Many peo­ple are in love with the Sin­gle­ton pat­tern. Oth­ers — a small minor­ity, I sus­pect — con­sider it a mis­take, an anti-pattern, or some­thing that was only ever included in the Design Pat­terns book as a life­line to pro­ce­dural pro­gram­mers who couldn’t really fig­ure out this OOP thing.

I won’t pre­tend to be half as clever as all the peo­ple who have already writ­ten about the prob­lems with sin­gle­tons years ago, and I don’t think I have any­thing new to bring to the table. But it is a pat­tern I learned to loathe years ago. (Sin­gle­tons do sound attrac­tive when you first hear of them. But they pale a bit when you end up hav­ing to tear up and rewrite half your code just because all your sin­gle­ton classes start reveal­ing their short­com­ings) And for a long time now, I’ve tried to con­vince other pro­gram­mers that Sin­gle­tons have some seri­ous prob­lems. Recently, a Stack­Over­flow com­ment sug­gested that I col­lect my argu­ments on the sub­ject, and write a sin­gle blog post on the topic. So here goes. I’ll even throw in a short­hand link from http://jalf.dk/singleton, to make it as easy as pos­si­ble to find.

Two wrongs don’t make a right

There are a lot of prob­lems with sin­gle­tons. In fact, it’s sur­pris­ing that so many peo­ple still con­sider the pat­tern use­ful, when it is afflicted with so many weak­nesses and flaws. How­ever, for now I will sin­gle out the two that I feel are the most fun­da­men­tal: not just prob­lems with how a sin­gle­ton works, but with what they’re try­ing to achieve:

A sin­gle­ton, as defined by the Gang of Four, com­bines two properties:

  • it guar­an­tees that exactly one instance of an object exists. While that one instance is typ­i­cally cre­ated lazily, so it doesn’t tech­ni­cally exist through­out the entire application’s life­time, it always seems to the pro­gram­mer as if pre­cisely one instance exists, and
  • it guar­an­tees global access to this one instance.

Let’s pick those apart a bit. The last one is eas­i­est: it is, by now, fairly com­mon knowl­edge that global state is bad. We don’t like global vari­ables, we don’t like sta­tic class mem­bers, we don’t like any­thing that makes it harder to iso­late bits of our code. Depen­dence on global state causes a lot of prob­lems: it hurts par­al­lelism, as access to global muta­ble state gen­er­ally has to be seri­al­ized through the use of locks. It makes depen­den­cies harder to detect and con­trol (any func­tion might silently decide to access our sin­gle­ton. The func­tion sig­na­ture says noth­ing about this, so we have to read the source code of the func­tion to deter­mine if this is the case. And because it is so con­ve­nient to always just add a ref­er­ence to a sin­gle­ton, we tend to do it a lot. When you have a sin­gle­ton, you quickly end up in a sit­u­a­tion where three out of four classes depend on it. How did that hap­pen? Why, log­i­cally speak­ing, do so many classes need direct access to the data­base? Or the ren­derer? Is that good design? Not only is this messy, it’s also painfully hard to fix after the fact. Once we have these depen­den­cies on global objects every­where, that’s a lot of code we need to change to elim­i­nate the global. Almost every class will be impacted by the change, and a huge num­ber of func­tions have to have their sig­na­tures mod­i­fied to take that extra para­me­ter replac­ing the global. Or even worse, the func­tion has to be com­pletely rewrit­ten to elim­i­nate the need for what­ever ser­vice the sin­gle­ton pro­vided. The more glob­als you have in your project, the more your depen­dency graph starts resem­bling spaghetti. And the harder it gets to clean it up.

It hurts reusabil­ity, as code taken from one project and inserted into another may break because it depended on glob­als not present in the new project. It hurts testa­bil­ity partly for the same rea­son, a unit test test­ing a class must sud­denly pro­vide a num­ber of glob­als as well just for the code under test to com­pile, but also because global state makes tests less deter­min­is­tic. One test might change the state of this global, affect­ing the out­come of the next test to run.

Glob­als are bad for a lot of rea­sons. They have their uses, no doubt about that, but we should be sus­pi­cious when­ever the solu­tion to a prob­lem involves global data. It might be the best solu­tion, but often, it is more trou­ble than it’s worth.

The other point is more sub­tle. Why do I object to a class enforc­ing that “only one instance may exist”? It’s really just com­mon sense. As the Agile move­ment tells us, we don’t really know what our code is going to look like tomor­row. Over the course of devel­op­ment, we have to adapt to changes, mod­ify our code, revise deci­sions already made. Why put road­blocks in front of us? Why make it harder to adapt to unfore­seen changes or requirements?

Today, I might think that I need only one log­ger instance. But what if I real­ize tomor­row that I need two? That’s not so far fetched. We may have one log we write ad-hoc mes­sages intended for debug­ging pur­poses, solely to be read by devel­op­ers, and another for­mal­ized log, where struc­tured mes­sages are writ­ten when pre­de­ter­mined events occur, so that the appli­ca­tion can be mon­i­tored in pro­duc­tion. Sure, we could define the two as com­pletely sep­a­rate classes, and then we’d only need one instance of each (but then we’d start dupli­cat­ing code). Or we could use the same log instance to write to both logs (but then the log­ging code would become more com­plex, hav­ing to inter­leave two sep­a­rate and non-overlapping logs.

Once we’ve accepted that an appli­ca­tion may need more than one log­ger, shouldn’t we do our­selves the favor of ensur­ing that our log­gers can be instan­ti­ated more than once, just in case it turns out to be the right thing to do? We’re not even adding any com­plex­ity, there’s no cost asso­ci­ated with this. On the con­trary, we’re remov­ing sig­nif­i­cant com­plex­ity. Thread-safe sin­gle­tons are sur­pris­ingly hard to get right. Depen­den­cies between sin­gle­tons are tricky and cir­cu­lar ones can cause them to blow up in all sorts of fun ways. And let’s not even get into how to han­dle any­thing our sin­gle­tons might do while the appli­ca­tion is shut­ting down. What if the data­base sin­gle­ton tries to write a sim­ple “good­bye” log mes­sage to the log sin­gle­ton? What if the log sin­gle­ton got destroyed before the data­base one? Ouch.

Sin­gle­tons are hard to write and hard to use. Remov­ing them only sim­pli­fies our code, so if it also enables us to bet­ter adapt to unfore­seen require­ments, why shouldn’t we remove them?

Not con­vinced? Let’s think of some other exam­ples then:

  • the appli­ca­tion con­fig­u­ra­tion should be a sin­gle­ton, right? We obvi­ously can’t have more than one of those! Wrong. We can. We often do. Think about what hap­pens when the user opens the “Options” screen and mod­i­fies the set­tings. Dur­ing that time, two sets of set­tings exist: the “applied” set­tings that are cur­rently in effect, and the “spec­u­la­tive” ones, cur­rently being picked out by the user. Once he clicks OK, the spec­u­la­tive changes should be applied, replac­ing the ones that were pre­vi­ously in effect. But until then, we have two sets of set­tings to maintain.
  • a data­base con­nec­tion pool then! If we have more than one pool of con­nec­tions, we can’t effi­ciently share them! Cor­rect, but per­haps we don’t want to share them. Per­haps I want to ensure that library A has one pool of 10 con­nec­tions avail­able to it, com­po­nent B has a smaller pool of 3 con­nec­tions, an com­po­nents C, D and E use the global pool with how­ever many con­nec­tions it sup­plies. That would ensure that no mat­ter the num­ber of threads run­ning in com­po­nent B, it’ll never starve out other com­po­nents try­ing to access the data­base. It can never hold more than three con­nec­tions, leav­ing room for other com­po­nents. Of course, in the com­mon case, we do want all con­nec­tions to be shared in one sin­gle pool. But per­haps not always. So yes, there should prob­a­bly be a glob­ally acces­si­ble default pool avail­able. But why shouldn’t it also be pos­si­ble to define new local pools if the user deems it nec­es­sary? Why limit our­selves to one instance?

And even if you do come up with some case where we absolutely must never have more than one instance, where it would make the sky come crash­ing down on us, con­sider test­ing. Con­sider that each of your unit tests should set up the envi­ron­ment it needs, and run within that envi­ron­ment, in iso­la­tion from other tests. That means that every test should cre­ate its own log­ger instance, or data­base pool instance, or what­ever else our sin­gle­tons are doing, just so it can avoid being pol­luted by state­ful changes made by ear­lier tests. Each unit test for the Direct3D ren­derer should set up its own ren­derer object. Each physics sim­u­la­tion test should ini­tial­ize the physics engine first, and shut it down again after use. Sin­gle­tons don’t eas­ily allow that. Sure, we can extend them with explicit Create() and Destroy() meth­ods, but then our abstrac­tion is start­ing to get leaky. We can no longer assume that pre­cisely one instance exists, because we might have just destroyed the one that existed.

The “exactly one instance” guar­an­tee removes flex­i­bil­ity from our code that we may need, in order to enforce a con­straint that we def­i­nitely don’t need. Where’s the harm in allow­ing the user to cre­ate more than one instance if he decides to?

C++ pro­gram­mers are famil­iar with std::cout, the stan­dard out­put stream. Funny thing about this, it is a sim­ple global object. We can obvi­ously never have more than one stan­dard out­put stream. But we can have more than one stream. The stan­dard library just ini­tial­izes one of them to point to the stan­dard out­put, and saves it as a global vari­able. We don’t need it to be a sin­gle­ton, we don’t even need it to be a sta­tic class spe­cially defined for the pur­pose. We just need a stream, defined some­where where it’s glob­ally accessible.

True, a suf­fi­ciently stu­pid pro­gram­mer could cre­ate a new stream when he intended to write to std::cout, and true, a sin­gle­ton imple­men­ta­tion would have pre­vented that. But is it worth it? When was the last time you saw some­one acci­den­tally invoke std::ostream() << "Hello world";, when they intended to write std::cout << "Hello world";? It’s not the most com­mon typo I’ve seen.

We don’t need to pre­vent mul­ti­ple instan­ti­a­tions. If we want only one instance, we just instan­ti­ate the class once, and refer to that instance when­ever we need it, end of story. We don’t need the com­piler to slap us over the wrists if we do cre­ate mul­ti­ple instances, because we never do so by mis­take. If we do it, it’s because we have a rea­son. It’s because our ini­tial assump­tion that only one instance was needed, turned out to be wrong!

So there you have it. A sin­gle­ton com­bines two neg­a­tive qual­i­ties. It takes the “you can never cre­ate a sec­ond instance of this class” con­straint, which hardly ever makes sense, and even when it does, does not typ­i­cally need to be enforced by the com­piler, and com­bines it with a global object, giv­ing us all the down­sides of both!

Two wrongs don’t make a right. Not even if they were described as a good idea by some guys 15 years ago. They’re still no greater than the sum of their parts: two wrongs. One bad thing com­bined with another bad thing, cre­at­ing a very bad thing.

Too many pro­gram­mers rely heav­ily on sin­gle­tons to solve a prob­lem they never had. They never needed a compile-time guar­an­tee that mul­ti­ple instances of a class can never be cre­ated. They just needed one instance to be created.

Some­times, we do need glob­als, yes. In those cases, make old-fashioned glob­als. Use sta­tic class mem­bers, or if the lan­guage allows it, global (non-member) objects. Or use the Mono­state pat­tern, or what­ever you feel is the clean­est solu­tion. But remem­ber that the prob­lem you’re try­ing to solve is “enabling global access to this data”. No more, no less. You do not want a solu­tion which sneaks com­pletely unre­lated con­straints and lim­i­ta­tions in through the back door.

And while I can’t per­son­ally think of many cases where this is true, you might also run into sit­u­a­tions where it is truly nec­es­sary to pre­vent more than one instance of a class from ever exist­ing. Again, I can’t think of what sit­u­a­tion this might be, but I won’t rule out that it can occur. If it does, then enforce that con­straint alone. But don’t go around pro­vid­ing global access to the object as well. What­ever spe­cial­ized pur­pose your “one instance only” class serves, it’s highly unlikely that every­one should be allowed access to it. So don’t make it a global.

Most of the time, your classes should have nei­ther of these attrib­utes. Some­times, rarely, they may need one of them. But the sin­gle­ton pat­tern imbues the class with both prop­er­ties, and that is just a plain bad idea.

Share and Enjoy: These icons link to social book­mark­ing sites where read­ers can share and dis­cover new web pages.
  • Digg
  • del.icio.us
  • StumbleUpon
  • Reddit
  • Technorati

Tags: , , ,

24 Responses to Singletons: Solving problems you didn’t know you never had since 1995

  1. GMan says:

    Aw, shucks. :P

  2. sheepsimulator says:

    I think your’e get­ting a lot bet­ter at mak­ing your argu­ment against Sin­gle­ton. I think the rea­sons you’ve laid down in your blog post are very coher­ent here, at least moreso than your argu­ments on SO have been in the past. Although, it’s been sev­eral months since I’ve read your argu­ments on it.

    I see your point now and mostly get it. How­ever, there is one rea­son that you didn’t address that might defend a singleton.

    Pro­gram­mers are peo­ple, and peo­ple do silly things some­times. Peo­ple may try to cre­ate more than one of some­thing where there should only be one of. The advan­tage of the sin­gle­ton idiom in that case is that it people-proofs part of it in some basic programming/use cases, say when out­side users are work­ing on a library that you wrote. In a library, you may wish to sup­press mul­ti­ple copies of a sin­gle object. One can actu­ally enforce this, idiomat­i­cally, with the Sin­gle­ton pat­tern. If one sim­ply tried using glob­als, mul­ti­ple copies could occur with­out the designer of the class allow­ing it, lead­ing to some con­fu­sion. Note that the devel­oper of the class wouldn’t use the object as a sin­gle­ton, as he/she would need to unit test it.

    Using a global as a sub­sti­tute works well if your pro­gram­mers under­stand the code base well enough to know that they shouldn’t make another instance of that object. You assume, I guess, that the pro­gram­mers are smart enough to fig­ure that out. I’m still unclear in my mind whether or not that’s a good assump­tion to make.

    Maybe you can think of a coun­ter­ar­gu­ment for this.

  3. jalf says:

    Per­haps I can. It depends on what kind of assump­tions you’re will­ing to make about the peo­ple who have access to the code.

    I like to assume that peo­ple using my code are com­pe­tent. I’m not naive enough to actu­ally believe it to be the case, but incom­pe­tent devel­op­ers will man­age to break the code no mat­ter what I do, so why bother with them?

    But what sit­u­a­tions can you imag­ine where the library devel­oper might know that only one instance makes sense, but where the library user would nev­er­the­less instan­ti­ate mul­ti­ple objects?

    Usu­ally, the “you only need one instance” infor­ma­tion is con­veyed eas­ily through sim­ple nam­ing and/or doc­u­men­ta­tion. If I know that an object is respon­si­ble for, say, ren­der­ing all objects in my scene graph, then it is pretty intu­itive that another instance won’t have access to the same scene graph, and so won’t be very use­ful. As a library user, I know intu­itively that this one object is all I need, because it is asso­ci­ated with the data I want it to be asso­ci­ated with.

    Or take the std::cout exam­ple from my post above. You’re right, a suf­fi­ciently dumb library user could instan­ti­ate another std::ostream when he intended to write to the stan­dard out­put, but in real­ity, it just doesn’t hap­pen, because real-world users of the stan­dard library know that std::cout is the stan­dard out­put stream, and they know they only need that one instance.

    Can you think of a sit­u­a­tion where the library user might mis­tak­enly believe that cre­at­ing mul­ti­ple instances is war­ranted? I can’t. I won’t rule out that such sit­u­a­tions exist, but in the com­mon cases (see std::cout) it isn’t an issue.

    It’s not that I assume pro­gram­mers in gen­eral are smart enough to fig­ure out how to use my library. It’s just that those who aren’t will man­age to break it no mat­ter what I do. Sure, I could sprin­kle sin­gle­tons all over it, but that still wouldn’t save them from them­selves. There are still hun­dreds of ways in which they could break my library: pass­ing invalid para­me­ters to func­tions, free­ing resources allo­cated by the library and so on.

    Of course, a final point is that you’re not argu­ing for a sin­gle­ton. You’re argu­ing for a “class-that-enforces-that-exactly-one-instance-will-exist”. That’s only half of the sin­gle­ton. The sin­gle­ton also pro­vides global access. If you really think that enforc­ing the 1-instance-limit is best, then do that, but how does that excuse mak­ing the same object glob­ally accessible?

  4. gf says:

    Ah, you did write about it — nice to see your argu­ing col­lected in one article.

  5. Tom Plunket says:

    Good points made, espe­cially the ones relat­ing to cout vs. ostream. I per­son­ally feel the “what if another instance of the thing can’t be instan­ti­ated” is a weak argu­ment; the con­struc­tion of an object should require enough con­text to get a use­ful object, so if some­one wants to cre­ate their own Log­ger instance that’s fine– but they’ll need to con­fig­ure it prop­erly if it’s going to do any­thing use­ful and it should be obvi­ous to any­one who spends ten min­utes in the code that that’s not how every­one else gets their mes­sages out to the world.

    Any­way– I see Sin­gle­tons as addi­tional com­plex­ity on top of the over­whelm­ing com­plex­ity that muta­ble global state itself brings. I don’t want that muta­ble global state in the first place, so Sin­gle­tons bring no value to me, personally.

    I don’t think igno­rance of the code­base is a fruit­ful argu­ment, one way or the other; peo­ple will do what­ever they want to do, and some­times peo­ple screw up. The best way to code (IMO) is such that screw ups are shown quickly and obvi­ously. Glob­als tend to make this more dif­fi­cult, as well.

    The most use­ful state­ment made, I must say, is that of arti­fi­cially con­strain­ing your objects. What’s the prob­lem if some­one instan­ti­ates another instance of this class? (and if they do it wrong, report the error promptly and unambiguously!)

  6. Scott says:

    What I’ve taken to say­ing lately is that Sin­gle­ton should be an Appli­ca­tion design ques­tion rather than a Class design ques­tion. If in your spe­cific appli­ca­tion it’s con­ve­nient to have one globally-accessible instance of a cer­tain type, that’s great, but there’s no rea­son to write the class in such a way that the class needs to know about that decision.

    Of course, that doesn’t pre­vent some­one using another instance, but if the appli­ca­tion is archi­tected that way, you can’t get the other code to use the instance you cre­ated even if you wanted it to.

    BTW, it might not be a bad idea to write a bit about depen­dency injec­tion to add to your sin­gle­ton rants, since that’s in many ways a “do this where your cur­rent instinct is a sin­gle­ton, and you get all these advantages”.

  7. Dieter Govaerts says:

    Thanks for shar­ing this. You def­i­nitely have a point and I will con­sider never to use a Sin­gle­ton again.

  8. I started study­ing OOP less than a year ago. So, it is not dif­fi­cult that all of you are more aware of it than me.

    IMHO, I think it is not a bad idea to use Sin­gle­tons in order to avoid hav­ing mul­ti­ple instances of an object (i.e. the Model) and have a global access to the sin­gle instance.

    I agree with you about the fact that Sin­gle­tons increase hid­den depen­den­cies. But I also think you can solve the prob­lem get­ting those depen­den­cies vis­i­ble. Don’t you think you can assign a sin­gle­ton instance to a mem­ber vari­able of a class that needs it?

    Doing so, you make the depen­dency vis­i­ble and give your­self the oppor­tu­nity to remove the sin­gle instance con­straint if you made a bad assump­tion about it.

    Does it make sense? Do I have to apol­o­gize for my english? :)

  9. jalf says:

    @Adriano: Why do you need to “avoid” hav­ing mul­ti­ple instances of an object? I don’t need to do any­thing to “avoid” jump­ing into the sea. I don’t need to do any­thing to “avoid” buy­ing a plane ticket. Those things only hap­pen if I decide to do them. And like­wise, instances of an object only exist if I decide to cre­ate them. If I only need one instance of an object, why would I cre­ate two? Why do you feel that you need to do any­thing spe­cial to “avoid” cre­at­ing mul­ti­ple instances?

    The sec­ond part, about global access, is some­what more sub­jec­tive. Per­haps you really want global access to this object. In that case, go ahead and make it global. I think global access is nearly always the wrong thing, but it really doesn’t mat­ter. If you want global access, use a global. If you don’t want global access, don’t make it a global. Nei­ther case requires a singleton.

    I also think you can solve the prob­lem get­ting those depen­den­cies vis­i­ble. Don’t you think you can assign a sin­gle­ton instance to a mem­ber vari­able of a class that needs it

    Sure, you can do that. But then (1) why does it need to be a sin­gle­ton, why does it need to be glob­ally acces­si­ble, and (2) you still have no way to ensure that it’s never used in the “other” way. That’s what’s icky about sin­gle­tons. You don’t know if these hid­den depen­den­cies exist. They might all be made explicit as you expect, but there might also be a num­ber of“hidden” uses scat­tered around your code. You don’t know.

  10. So say you need access to a Set­tings class at var­i­ous hier­ar­chi­cal lev­els in your code, for instance the Appli­ca­tion, the Con­troller and the View. You could have a glob­ally acces­si­ble Sin­gle­ton and have code like:

    SettingsClass.getSetting(‘showTooltips’)

    Or you have it be an instance var on the Appli­ca­tion class which is ref­er­enced by an instance var on the Con­troller class which is ref­er­enced by an instance var on the view and so on… You end up with the following:

    self.parentController.parentApplication.settings.getSetting(‘showTooltips’);

    Which is a (very!) hid­den depen­dency. Or you do…

    Application’s init: self.viewController.showTooltips = settings.getSettings(‘showTooltips’) viewController’s init: self.view = this.showTooltips

    …and cre­ate tons of code with a mul­ti­plic­ity of by way of prop­erty names, mak­ing changes such as refac­tor­ing a seri­ous sweat.

    What I’m ask­ing really, is what about the case for the sin­gle­ton (or at least a global vari­able) where it reduces com­plex­ity for appli­ca­tion areas which aren’t resource intensive?

    Like many things in pro­gram­ming isn’t it a trade off between sim­plic­ity and cov­er­ing all poten­tial future cases?

  11. jalf says:

    How is the first one a hid­den depen­dency? It’s clear exactly how the cur­rent object retrieves the set­tings object. We know that it does this through its ref­er­ence to the par­ent con­troller, which has a ref­er­ence to the par­ent appli­ca­tion, and so on. We have explic­itly said in the code that this code requires a ref­er­ence to the par­ent con­troller, so it is not a hid­den depen­dency. I can look at the object’s con­struc­tor and see that it takes a ref­er­ence to the object it needs to ref­er­ence. Or I can fol­low the code the other way around: Start at wher­ever the settings object is cre­ated, and then read along to see where it is passed to. If I fol­low the code from that point, it nat­u­rally takes me to every use site.

    On the other hand, in your sec­ond snip­pet, it’s not clear where this set­tings object comes from. And I can’t fol­low the uses of the object. If I start at the con­struc­tion of the settings object, I imme­di­ately run into “it’s stored into a sin­gle­ton, which is… just there. At some point, some­one might call getInstance on it, but I don’t know who does that, or when or why.

    So I dis­agree with your analy­sis of dependencies.

    On the other hand, it is cer­tainly more con­ve­nient to just make the set­tings object glob­ally accessible.

    So go ahead and do that. But it doesn’t need to be a sin­gle­ton to achieve that goal. Just a sin­gle global/static instance will allow every­one to access the set­tings object if they want to. There’s no need for mess­ing around with sin­gle­tons and all the other prob­lems they cause.

    Sin­gle­tons are global, but glob­als are not sin­gle­tons. If you need a global, that doesn’t mean you have to use a singleton.

  12. Hid­den in the sense that the low­est level object which is mak­ing the call now has 2 more depen­den­cies in addi­tion to its depen­dency on the set­tings class — per­haps not hid­den from it’s per­spec­tive but from the top level van­tage point, doesn’t the depen­dency on Set­tings seem quite buried? Say you changed the struc­ture of the set­tings object and needed to find all ref­er­enc­ing code…

    At first I was inclined toward your stance on using a sim­ple global vari­able which is init’ed per­haps, with the app startup. Upon reflec­tion how­ever, I’m not sure I see the dif­fer­ence between this and the sin­gle­ton pat­tern, other than that the later pack­ages the global vari­able (as a sta­tic) and has a self con­tained ini­tial­i­sa­tion. Some might even argue that this is more in keep­ing with Sin­gle Respon­si­bil­ity Prin­ci­ple. What do you think?

    Thanks for the thought pro­vok­ing and detailed dis­cus­sion by the way. It’s very per­ti­nent to the code I’m writ­ing as we speak :)

  13. Yarin says:

    Thanks for a great arti­cle. I’ve been mud­dling through the sin­gle­ton debate for a long time– this arti­cle cleared the fog. Done with them. Keep writing.

  14. Xander says:

    Very inter­est­ing arti­cle: you have [i]almost[/i] talked me out of using a singleton-like design for the Log and Resource­M­an­ager I am work­ing on.

    You say your­self that some­times global vari­ables are nec­es­sary, but there is no need to impose the sin­gle instance rule. I cer­tainly agree with this.

    How­ever, sup­pose you have a tem­plate [i]class Singleton[/i] which pro­vides a singleton-like design pat­tern for [i]class T[/i]. To me, this seems to pro­vide a safer global access than a plain global (because one can fairly eas­ily add inbuilt mutexes etc. and one doesn’t have order of con­struc­tion prob­lems). On the other hand, because the Sin­gle­ton design is imple­mented in its own tem­plate class, it doesn’t actu­ally pre­vent other instances being created.

    What do you think of this approach? Per­haps it would be clearer to rename [i]Singleton[/i] to [i]Global[/i], but that name could be some­what con­fus­ing too (since only one object of that type can be instan­ti­ated). How­ever, it seems to me that this essen­tially matches your cri­te­ria (imposes glob­al­ity, which is some­times desir­able, but not strictly sin­gle instan­ti­a­tion), but in a safer man­ner than a nor­mal global variable.

  15. jalf says:

    @Xander: first, to be pre­cise, I don’t believe I ever said that glob­als are ever nec­es­sary. I said that they may some­times be con­ve­nient, or may even be the prefer­able solu­tion. But not nec­es­sary. :)

    And even when you think mak­ing an object global is a good idea, it often isn’t. Tak­ing your resource man­ager as an exam­ple, why does it need to be global? The vast major­ity of your code shouldn’t need to know about it. Pass it around to the few classes that do need it. Or per­haps even bet­ter, ask your­self why you need a resource man­ager at all. “Man­ager” classes are always a warn­ing sign. What does it mean to “man­age” a resource? What kind of man­age­ment does it need? Can’t a resource take care of itself? What respon­si­bil­i­ties does a “man­ager” have? Rename it, split it up into mul­ti­ple smaller classes, or remove it entirely. And very likely, you’ll find that there’s no need to make it global either.

    You’ll also find that it’s not a true “global” in any case. It has a lim­ited life­time (it doesn’t make sense to “man­age” a Direct3D resource before your D3D Device has been cre­ated, or after it has been destroyed, for example).

    As to your main point, sev­eral points come to mind:

    • what would your pro­posed mutex do? Just ensure that calls to instance() are seri­al­ized? That’s only nec­es­sary at con­struc­tion (and not even then, assum­ing a com­piler which prop­erly imple­ments C++11’s mem­ory and thread­ing mod­els), and I would much rather just explic­itly con­trol the object’s con­struc­tion in any case (see below), mak­ing that prob­lem go away entirely. So doing so really solves a non-problem. And it won’t make the actual “inner” object instance thread-safe either. So I don’t buy the “safety” thing. Is there some other safety ben­e­fit I’m not seeing?
    • I’ve come to dis­agree with the “order of con­struc­tion” argu­ment. Most of the prob­lems I’ve encoun­tered in the real world with sin­gle­tons have been related pre­cisely to order (and time and place) of con­struc­tion: with a sin­gle­ton, I sim­ply have no clue when it’s going to be ini­tial­ized. That is often a prob­lem, espe­cially for objects you may want to param­e­trize (which file should your log­ger out­put to, for exam­ple? Pre­sum­ably your resource man­ager needs to know about your OpenGL con­text or Direct3D device (Resource man­agers tend to imply peo­ple are mak­ing a game, in my expe­ri­ence :)). With sin­gle­tons, pass­ing such para­me­ters isn’t easy, because you have no clear point at which it is instan­ti­ated.

    So if order of con­struc­tion mat­ters, that’s a very strong rea­son to avoid mak­ing it global. Con­struct your objects explic­itly, in main or another function.

    Of course, if you absolutely want global’ish access, you can cre­ate the object locally in main, for exam­ple, and then set a global pointer to point to it. Then you still con­trol order and time of con­struc­tion, while also pro­vid­ing a means for code to access the object globally.

    But gen­er­ally, my rule of thumb is that glob­als should not depend on order of con­struc­tion (they shouldn’t need to access other globals).

  16. Hanspeter says:

    Ok, I can under­stand the argu­ments stated against sin­gle­tons so far.

    How­ever, what do you think about hard­ware abstract­ing soft­ware? Let’s say I’ve got var­i­ous classes encap­su­lat­ing hard­ware com­po­nents of a sys­tem (e.g. inter­faces, timers, etc.).

    (The sys­tem might not nec­es­sar­ily be based on PC-platform but might be an embed­ded system)

    As each hard­ware com­po­nent exists exactly once and prob­a­bly also needs con­cur­rency access con­trol, it is in my opin­ion a bit dan­ger­ous and counter intu­itive to allow the cre­ation of more than one object.

    In my opin­ion the num­ber of soft­ware objects should “mir­ror” the num­ber of the hard­ware objects.

    What do you think?

  17. jalf says:

    How­ever, what do you think about hard­ware abstract­ing soft­ware? Let’s say I’ve got var­i­ous classes encap­su­lat­ing hard­ware com­po­nents of a sys­tem (e.g. inter­faces, timers, etc.).

    In short: I don’t buy it. There are gen­er­ally two ways in which soft­ware inter­acts with hardware:

    • as a form of dri­ver, in which case it doesn’t have a high-level “object” model of the hard­ware. it talks to the hard­ware using what­ever low-level pro­to­cols the hard­ware expects. A GPU dri­ver shouldn’t have a “GPU” sin­gle­ton object. It should just know at which address to find the GPU it is sup­posed to man­age, and read/write the cor­rect data at that address. This is prob­a­bly what will typ­i­cally hap­pen in an embed­ded sys­tem. You talk directly to the hard­ware. And you cer­tainly don’t want to offer global access to the hard­ware. It’s a pain in the ass to com­mu­ni­cate with, so you only want that to be pos­si­ble to the pieces of code that really need it. Mak­ing it a sin­gle­ton would be sui­cide. Sud­denly every piece of code can com­mu­ni­cate with this exter­nal hard­ware which is hard enough to man­age robustly in the best of cases.
    • as a high-level user of the hard­ware (a game using a Direct3D Device, or some appli­ca­tion using a COM port, or a socket), in which case it’s not really the hard­ware at all. It’s vir­tu­al­ized, abstracted and wrapped. And any half-decent abstrac­tion will need to be able to han­dle mul­ti­ple instances. I can cre­ate mul­ti­ple D3D Devices, even if I have just one GPU (and still, I may have more than one GPU). I can open mul­ti­ple COM ports, talk to mul­ti­ple print­ers and open mul­ti­ple sock­ets. Sure, behind all those sock­ets is, prob­a­bly, a sin­gle NIC, but only the dri­ver sees that. Every­one else sees an abstract “socket” model, where I can cre­ate as many sock­ets as I like.

    Per­haps you a coun­terex­am­ple; some con­trived embed­ded sys­tem where it makes per­fect sense to model a piece of hard­ware as an object, and because it is imprac­ti­cal to abstract it enough to allow mul­ti­ple instances of the object, you make it a sin­gle­ton. Per­haps. But then you’ll need to be much more spe­cific. In the gen­eral case, I don’t see it. And if you do find such an exam­ple, remem­ber that you also need to jus­tify giv­ing all the code global access to the hardware.

    In my opin­ion the num­ber of soft­ware objects should “mir­ror” the num­ber of the hard­ware objects.

    Why? In which sit­u­a­tions? With which kinds of hardware?

    With­out more con­text, it’s really impos­si­ble to dis­cuss. Once again, it would be absurd to limit me to one “net­work” object just because I have just one NIC. I need one object for each con­nec­tion I want to main­tain. It’s crazy to limit me to one “GPU object” for each phys­i­cal GPU. I need an object for each con­text in which I want to render.

    On a PC-like sys­tem, with mul­ti­pro­cess­ing and vir­tual mem­ory and every­thing, it makes no sense, ever. Even if you make the GPU “object” a sin­gle­ton, that still means that each process can cre­ate its own GPU. That makes no sense, so the GPU dri­ver has to be able to han­dle mul­ti­ple instan­ti­a­tions any­way. And if it can han­dle that, why not allow the indi­vid­ual process to cre­ate mul­ti­ple instances if it wants to? On a PC, it’s a ridicu­lous notion.

    In an embed­ded sys­tem where you have just one process, no vir­tual mem­ory, no fancy vir­tu­al­iza­tion or abstrac­tion, there are obvi­ously cases where you don’t want to present such a vir­tu­al­ized high-level abstrac­tion. But then I ques­tion the need for any kind of class/object.

    If you go high-level, the hard­ware restric­tions are irrel­e­vant. If you go low-level, then the hard­ware isn’t an “object” at all. Objects are cre­ated and destroyed and copied. They have a life­time. The hard­ware is just there.

  18. Damsterdam says:

    Just a ques­tion from a newbie :

    For exam­ple, in PHP, if I cre­ate a template’s class, which has a method to add views into a pile. This method can be called from sev­eral loca­tions, on a sin­gle instance (I mean the cre­ation of just one web page).

    This pile must be save between each instance of this class, before the final out­put, no ?

    So a Mono­state pat­tern, just to make this prop­erty sta­tic, is a good idea, no ? How to do other way ?

    I think in some project, mono­state pat­tern is not so evil… And necessary :/

  19. Danguafer says:

    So… I had one REAL need to use sin­gle­ton in C++, I cre­ated an Appli­ca­tion singleton.

    And my imple­men­ta­tion approach is to use a global vari­able instan­ti­at­ing a class with sta­tic prop­er­ties, includ­ing a pub­lic con­struc­tor and a sta­tic ini­tial­iza­tion con­trol variable.

  20. jalf says:

    @Damsterdam: instead of rely­ing on global data, you can always just pass around ref­er­ences to those who need them. If every­one holds a ref­er­ence to your instance, then they can access it with­out it being global. The only ques­tion is whether this is nicer than a global-based solu­tion, such as the Mono­state pat­tern. It might not be, maybe a Mono­state is really bet­ter in your case. But it’s not nec­es­sary. :)

    @Danguafer: why was that a “REAL” need? Why did your Appli­ca­tion class need to be a sin­gle­ton? It’s a silly idea, and it pre­vents you from doing a lot of things that might be use­ful. (How about a unit test which cre­ates an Appli­ca­tion, runs some test against it, and closes it down?)

  21. Wayne says:

    The only time I use sin­gle­tons is when defin­ing an API in a library. Take for exam­ple a device and you want to turn on the back­light. The options I see are:

    1. C style func­tion deviceTurnOnBacklight();

    2. Sta­tic method Device.turnOnBacklight();

    3. Sin­gle­ton class + instance method Device.getInstance().turnOnBacklight();

    I have always strug­gled to decide which of these par­a­digms to use. In a lan­guage like Java, option (1) is not avail­able. I usu­ally choose option (3) because I don’t see value in mak­ing every API func­tion a sta­tic method. Per­haps it doesn’t make a difference.

    Can you com­ment on this? – Wayne

  22. Lavnish says:

    i com­pletely agree with this arti­cle , talk­ing of trou­ble with sin­gle­tons , for some cases i see Aspect Ori­ented pro­gram­ming as a solu­tion …instead of using a Log­ger Sin­gle­ton use a Log­ger Aspect

  23. bamsham says:

    Sin­gle­tons sat­isfy a very basic need. It is up to the devel­op­ers to use ( or abuse ) it. Think of it as wheels, what you do with them is up to you.Many things go together to form some­thing use­ful like a car that can con­sume wheels( you will need brakes, etc).

    1. Not every one knows how to use Sin­gle­ton prop­erly. Good pro­gram­mers imple­ment pure code by ana­lyz­ing appli­ca­tion sce­nario. It could be that sin­gle­tons do not sat­isfy all the cri­te­rion. And Many pro­gram­mers copy /paste code. You will need Han­dlers, Man­agers and Helper classes to effec­tively use a Singleton.

    2. The basic Idea that it is one object at any given moment and it is global is a lan­guage depen­dency. OOP lan­guages like Java / C# man­date Sin­gle­ton to be a sta­tic entity at the class level.

    Think of it if instead of defin­ing a class to morph into Sin­gle­ton there could a lan­guage level functionality.

    3 Steps to define a Sin­gle­ton Class : a) cre­ate pri­vate global vari­able. b) cre­ate pri­vate con­struc­tor. c) cre­ate a global method.

    Code for ref­er­ence{ every­one knows this bit} pub­lic class SomeSin­gle­ton { pri­vate sta­tic SomeSin­gle­ton _instance = null;

    private SomeSingleton()
    

    { }

    public static SomeSingleton GetInstance()
    {
      if(_instance==null)
      { 
          _instance = new SomeSingleton();
      } 
      return _instance;
    }
    

    }

    We can have a dif­fer­ent way of declar­ing the Sin­gle­ton as a new type of class. Using a reserve word “UniqueClass”

    pub­lic Unique­Class SomeSingleton {

    }

    Now keep using it nor­mally. com­pile should take care of mak­ing sure that it is a sin­gle­ton behind the scenes. Thread –safe and what not.

    Food for thought.

Leave a Reply

Name and Email Address are required fields. Your email will not be published or shared with third parties.