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, it seems like I’m even get­ting noticed for it among the users of StackOverflow.

First, oneuser posts an answer to one ques­tion, and I com­ment with a mild dis­agree­ment, and the dis­cus­sion goes on for a few more com­ments. As sin­gle­ton rants go, this one is pretty mild, and I don’t really think about it any fur­ther. Then, a few weeks later, I dis­cover his blog and this post. Wow! A con­vert. A per­son I know to be a smart and a knowl­edge­able pro­gram­mer has changed his mind in response to some­thing I said… I’m flattered.

And today, I noticed another ques­tion being posted, which had both Boost and Sin­gle­tons in the title — how could I resist? Two sub­jects I enjoy talk­ing about, even if the things I say about them are very dif­fer­ent. Sur­pris­ingly, the com­ments there already men­tioned me, and some of my ear­lier answers regard­ing sin­gle­tons. Should I be flat­tered or wor­ried that peo­ple have started bring­ing my name up when dis­cussing Singletons?

Any­way, one of the com­ments also sug­gested I write a blog post describ­ing my argu­ment in detail. So I will. I’ll even throw in a redi­rect 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: , , ,

12 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 :)

Leave a Reply

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