Testing Blog

Root Cause of Singletons

Wednesday, August 27, 2008
Share on Twitter Share on Facebook
Google
Labels: Misko Hevery

13 comments :

  1. mike bayerAugust 27, 2008 at 10:53:00 AM PDT

    what's your take on Spring transaction manager (http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html ) ? no good, huh ?

    ReplyDelete
    Replies
      Reply
  2. Richard QuirkAugust 27, 2008 at 12:49:00 PM PDT

    I think "Singletons considered harmful" is just a short way off now :-)

    So how would one go about getting rid of Singletons? I use them for stuff that, well, only needs 1 instance. I would have to pass a non-singleton through to the method or function that needs it. Typically the reference would end up getting passed through several classes and calls. A Singleton short circuits that by popping up right were it is needed. e.g. a simple example:

    class B {
      void doMoreStuff() {
        C::instance().setSomething();
      }
    }

    class A {
      void doStuff() {
        b->doMoreStuff();
      }
    }

    int main() {
      A a;
      a.doStuff();
    }

    Typically if A is the runner or controlling class, there's only 1 of it anyway, created in the main(). So adding a C instance member variable to A means you would have to pass it in everywhere that needed to use it. i.e. after de-singletonising:

    class B {
      void doMoreStuff(C *c) {
        c->setSomething();
      }
    }

    class A {
      A(): c_(new C) {}

      void doStuff() {
        b->doMoreStuff(c_);
      }
      C *c_;
    }

    int main() {
      A a;
      a.doStuff();
    }

    Or create all the singletons in main() and inject them into the A instance's constructor with a factory. But in the end the no-longer-a-singleton has to get to where it's used, and that can be a real pain. Singletons make life easier in these cases; a guilty pleasure! I think the answer to "what can be done?" will inevitably be "it depends".

    ReplyDelete
    Replies
    1. AnonymousNovember 25, 2012 at 2:08:00 PM PST

      Misko talks about this concern here: http://www.youtube.com/watch?v=-FRm3VPhseI#t=31m20s

      re "inject them into the A instance's constructor": Not necessarily. In your specific example, A does not collaborate with C, not directly anyway; A directly collaborates with B only. Therefore, you should instead do something like this:

      int main() {
      C c;
      B b(c);
      A a(b);
      }

      There isn't that much passing around of c. Yes, c needs to be passed to b. This is a Good Thing(TM), because it is now clear that B depends on C. Singletons obfuscate this fact. Misko also talks about this problem earlier in the same video: http://www.youtube.com/watch?v=-FRm3VPhseI#t=18m52s

      Delete
      Replies
        Reply
    2. Reply
  3. UnknownAugust 28, 2008 at 3:25:00 AM PDT

    @Quirky

    having a singleton directly where you needs it without having to pass it thru many layers is indeed really seductive.

    From my experience, it only prooves that you have a bad architecture to begin with.

    Sometimes the architecture is something you can't change, so singleton may have some use there.

    But mark my words, singleton are nasty boomerangs, they will come back in your face at full speed.

    I have never seen a Singleton survive in big code base focused on quality, in the long run, they are simply to dangerous/painful. They can exist during a period of time, but they are replaced ASAP, before they rigidify the system around them.

    For example, singletons and multicore/multiprocesses are really really something you don't want to mix.

    ReplyDelete
    Replies
      Reply
  4. UnknownAugust 28, 2008 at 3:25:00 AM PDT

    No that I disagree that prolific referencing of global data (i.e. abuse of the singleton pattern) leads to brittle / hard to test software ...

    The irony here is that the vast majority of IoC containers require heavily on use of the singleton pattern themselves ;)

    Think ..

    ContextRegistry.GetContext().GetObject("MyType")

    in Spring.NET for instance ;)

    ReplyDelete
    Replies
      Reply
  5. vvagellAugust 28, 2008 at 6:56:00 AM PDT

    As you said, I think "most developers recognize" that old-school global variables (like those heavily abused in C) are a blight. But this is really a bit of a nostalgic argument, and I don't know that it's directly relevant to Singletons.

    Singletons can certainly be abused, but I'd say they're one step up from C-style global vars. At least they let us categorize global vars and behaviors into classes, to give hints as to purpose and improve serviceability.

    I think the core problem really stems from (what is incidentally your primary viewpoint) testability concerns. And from there I can agree with you, and have been reviewing your previous articles for suggestions on how to improve this issue.

    Nonetheless, I think it's a mistake to wholly throw out Singletons as remnants of caveman code. They have their place, and they are an improvement over what "most developers" think of as global state.

    ReplyDelete
    Replies
      Reply
  6. Gian Marco GherardiSeptember 8, 2008 at 1:30:00 PM PDT

    In my experience, i found singleton pattern useful for ValueObjects (aka immutable objects) or objects witout state. An example is .NET DBNull.Value, string.Empty and CultureInfo.InvariantCulture. You can use/make assertion based on the same instance also on your tests, so:
    Assert.AreEqual(DBNull.Value, m_target.Query());

    Bye

    ReplyDelete
    Replies
      Reply
  7. AnonymousSeptember 9, 2008 at 3:52:00 PM PDT

    Let's for the sake of argument say that Singleton is considered harmful. Just as Quirky asked, what can be done? Some concrete tips would be really handy I think.

    ReplyDelete
    Replies
      Reply
  8. UnknownMay 27, 2013 at 3:40:00 AM PDT

    Some Global states aren't bad. Some times you need inherit in constant values. And you can't make static values be inherited. So, some times is the solution not the design. I will give you a simple example:

    If u have a class Enterprise, and you want that everybody that inherited of Enterprise has some properties/methods implemented and these methods are constants for each class. So what you gonna do? Singleton! :)

    ReplyDelete
    Replies
      Reply
  9. UnknownMarch 5, 2014 at 10:25:00 AM PST

    Generally I agree with your points here, but it may be harmful in itself to make it canon that "Singletons are bad". Like any design pattern, they are an antipattern the moment that they're applied in the wrong context. However, there are plenty of instances where the mistake would be doing the opposite--state machines like OpenGL and OpenAL, as an example, only ever provide a single instance because they are tightly (and literally) bound hardware; a second GL object will not give you a second graphics system in the real world. Thus, making a GL object factory is a terrible and misleading idea. Anything bound to a singular real-world state machine basically requires either a singleton or a static class, and for me, singletons have been much more convenient. Additionally, if one is working with something highly resource-constricted, like cell phone or microcontroller source, the overhead of multiple objects can be crippling when only one is necessary, and decency suggests a Singleton restriction. There are instances where even global objects have their place, albeit rare ones.

    While the singleton pattern is often abused in places where a factory might be more appropriate, it is important to remember that it is most frequently applied in instances in which one is creating an API or toolkit. There are things that we don't want the next programmer to use the kit to have to think about, and often, those things have the necessity in them of only a single instance of a class existing.

    ReplyDelete
    Replies
    1. LLJanuary 5, 2016 at 8:59:00 PM PST

      But still, with say opengl you could just create an instance and pass it around to classes that need it. If you define it as a global variable instead then you have classes that 'secretly' access it. i.e. they don't tell you they access it in their interface, they just do it.

      Delete
      Replies
        Reply
    2. AnonymousApril 5, 2016 at 6:17:00 AM PDT

      I hear the "bound to hardware" argument a lot, but it's not actually very helpful. Hardware can change--not as fast as software, perhaps, but faster than API standards committees! Saying that "there will only be one of these" is the same as saying "my code is not future-proof."

      Delete
      Replies
        Reply
    3. Reply
  10. 256FXDecember 9, 2016 at 2:02:00 AM PST

    What are your views on Singleton VS Dependency Injection? (Ala Angular)

    ReplyDelete
    Replies
      Reply
Add comment
Load more...

The comments you read and contribute here belong only to the person who posted them. We reserve the right to remove off-topic comments.

  

Labels


  • TotT 104
  • GTAC 61
  • James Whittaker 42
  • Misko Hevery 32
  • Code Health 31
  • Anthony Vallone 27
  • Patrick Copeland 23
  • Jobs 18
  • Andrew Trenk 13
  • C++ 11
  • Patrik Höglund 8
  • JavaScript 7
  • Allen Hutchison 6
  • George Pirocanac 6
  • Zhanyong Wan 6
  • Harry Robinson 5
  • Java 5
  • Julian Harty 5
  • Adam Bender 4
  • Alberto Savoia 4
  • Ben Yu 4
  • Erik Kuefler 4
  • Philip Zembrod 4
  • Shyam Seshadri 4
  • Chrome 3
  • Dillon Bly 3
  • John Thomas 3
  • Lesley Katzen 3
  • Marc Kaplan 3
  • Markus Clermont 3
  • Max Kanat-Alexander 3
  • Sonal Shah 3
  • APIs 2
  • Abhishek Arya 2
  • Alan Myrvold 2
  • Alek Icev 2
  • Android 2
  • April Fools 2
  • Chaitali Narla 2
  • Chris Lewis 2
  • Chrome OS 2
  • Diego Salas 2
  • Dori Reuveni 2
  • Jason Arbon 2
  • Jochen Wuttke 2
  • Kostya Serebryany 2
  • Marc Eaddy 2
  • Marko Ivanković 2
  • Mobile 2
  • Oliver Chang 2
  • Simon Stewart 2
  • Stefan Kennedy 2
  • Test Flakiness 2
  • Titus Winters 2
  • Tony Voellm 2
  • WebRTC 2
  • Yiming Sun 2
  • Yvette Nameth 2
  • Zuri Kemp 2
  • Aaron Jacobs 1
  • Adam Porter 1
  • Adam Raider 1
  • Adel Saoud 1
  • Alan Faulkner 1
  • Alex Eagle 1
  • Amy Fu 1
  • Anantha Keesara 1
  • Antoine Picard 1
  • App Engine 1
  • Ari Shamash 1
  • Arif Sukoco 1
  • Benjamin Pick 1
  • Bob Nystrom 1
  • Bruce Leban 1
  • Carlos Arguelles 1
  • Carlos Israel Ortiz García 1
  • Cathal Weakliam 1
  • Christopher Semturs 1
  • Clay Murphy 1
  • Dagang Wei 1
  • Dan Maksimovich 1
  • Dan Shi 1
  • Dan Willemsen 1
  • Dave Chen 1
  • Dave Gladfelter 1
  • David Bendory 1
  • David Mandelberg 1
  • Derek Snyder 1
  • Diego Cavalcanti 1
  • Dmitry Vyukov 1
  • Eduardo Bravo Ortiz 1
  • Ekaterina Kamenskaya 1
  • Elliott Karpilovsky 1
  • Elliotte Rusty Harold 1
  • Espresso 1
  • Felipe Sodré 1
  • Francois Aube 1
  • Gene Volovich 1
  • Google+ 1
  • Goran Petrovic 1
  • Goranka Bjedov 1
  • Hank Duan 1
  • Havard Rast Blok 1
  • Hongfei Ding 1
  • Jason Elbaum 1
  • Jason Huggins 1
  • Jay Han 1
  • Jeff Hoy 1
  • Jeff Listfield 1
  • Jessica Tomechak 1
  • Jim Reardon 1
  • Joe Allan Muharsky 1
  • Joel Hynoski 1
  • John Micco 1
  • John Penix 1
  • Jonathan Rockway 1
  • Jonathan Velasquez 1
  • Josh Armour 1
  • Julie Ralph 1
  • Kai Kent 1
  • Kanu Tewary 1
  • Karin Lundberg 1
  • Kaue Silveira 1
  • Kevin Bourrillion 1
  • Kevin Graney 1
  • Kirkland 1
  • Kurt Alfred Kluever 1
  • Manjusha Parvathaneni 1
  • Marek Kiszkis 1
  • Marius Latinis 1
  • Mark Ivey 1
  • Mark Manley 1
  • Mark Striebeck 1
  • Matt Lowrie 1
  • Meredith Whittaker 1
  • Michael Bachman 1
  • Michael Klepikov 1
  • Mike Aizatsky 1
  • Mike Wacker 1
  • Mona El Mahdy 1
  • Noel Yap 1
  • Palak Bansal 1
  • Patricia Legaspi 1
  • Per Jacobsson 1
  • Peter Arrenbrecht 1
  • Peter Spragins 1
  • Phil Norman 1
  • Phil Rollet 1
  • Pooja Gupta 1
  • Project Showcase 1
  • Radoslav Vasilev 1
  • Rajat Dewan 1
  • Rajat Jain 1
  • Rich Martin 1
  • Richard Bustamante 1
  • Roshan Sembacuttiaratchy 1
  • Ruslan Khamitov 1
  • Sam Lee 1
  • Sean Jordan 1
  • Sebastian Dörner 1
  • Sharon Zhou 1
  • Shiva Garg 1
  • Siddartha Janga 1
  • Simran Basi 1
  • Stan Chan 1
  • Stephen Ng 1
  • Tejas Shah 1
  • Test Analytics 1
  • Test Engineer 1
  • Tim Lyakhovetskiy 1
  • Tom O'Neill 1
  • Vojta Jína 1
  • automation 1
  • dead code 1
  • iOS 1
  • mutation testing 1


Archive


  • ►  2025 (1)
    • ►  Jan (1)
  • ►  2024 (13)
    • ►  Dec (1)
    • ►  Oct (1)
    • ►  Sep (1)
    • ►  Aug (1)
    • ►  Jul (1)
    • ►  May (3)
    • ►  Apr (3)
    • ►  Mar (1)
    • ►  Feb (1)
  • ►  2023 (14)
    • ►  Dec (2)
    • ►  Nov (2)
    • ►  Oct (5)
    • ►  Sep (3)
    • ►  Aug (1)
    • ►  Apr (1)
  • ►  2022 (2)
    • ►  Feb (2)
  • ►  2021 (3)
    • ►  Jun (1)
    • ►  Apr (1)
    • ►  Mar (1)
  • ►  2020 (8)
    • ►  Dec (2)
    • ►  Nov (1)
    • ►  Oct (1)
    • ►  Aug (2)
    • ►  Jul (1)
    • ►  May (1)
  • ►  2019 (4)
    • ►  Dec (1)
    • ►  Nov (1)
    • ►  Jul (1)
    • ►  Jan (1)
  • ►  2018 (7)
    • ►  Nov (1)
    • ►  Sep (1)
    • ►  Jul (1)
    • ►  Jun (2)
    • ►  May (1)
    • ►  Feb (1)
  • ►  2017 (17)
    • ►  Dec (1)
    • ►  Nov (1)
    • ►  Oct (1)
    • ►  Sep (1)
    • ►  Aug (1)
    • ►  Jul (2)
    • ►  Jun (2)
    • ►  May (3)
    • ►  Apr (2)
    • ►  Feb (1)
    • ►  Jan (2)
  • ►  2016 (15)
    • ►  Dec (1)
    • ►  Nov (2)
    • ►  Oct (1)
    • ►  Sep (2)
    • ►  Aug (1)
    • ►  Jun (2)
    • ►  May (3)
    • ►  Apr (1)
    • ►  Mar (1)
    • ►  Feb (1)
  • ►  2015 (14)
    • ►  Dec (1)
    • ►  Nov (1)
    • ►  Oct (2)
    • ►  Aug (1)
    • ►  Jun (1)
    • ►  May (2)
    • ►  Apr (2)
    • ►  Mar (1)
    • ►  Feb (1)
    • ►  Jan (2)
  • ►  2014 (24)
    • ►  Dec (2)
    • ►  Nov (1)
    • ►  Oct (2)
    • ►  Sep (2)
    • ►  Aug (2)
    • ►  Jul (3)
    • ►  Jun (3)
    • ►  May (2)
    • ►  Apr (2)
    • ►  Mar (2)
    • ►  Feb (1)
    • ►  Jan (2)
  • ►  2013 (16)
    • ►  Dec (1)
    • ►  Nov (1)
    • ►  Oct (1)
    • ►  Aug (2)
    • ►  Jul (1)
    • ►  Jun (2)
    • ►  May (2)
    • ►  Apr (2)
    • ►  Mar (2)
    • ►  Jan (2)
  • ►  2012 (11)
    • ►  Dec (1)
    • ►  Nov (2)
    • ►  Oct (3)
    • ►  Sep (1)
    • ►  Aug (4)
  • ►  2011 (39)
    • ►  Nov (2)
    • ►  Oct (5)
    • ►  Sep (2)
    • ►  Aug (4)
    • ►  Jul (2)
    • ►  Jun (5)
    • ►  May (4)
    • ►  Apr (3)
    • ►  Mar (4)
    • ►  Feb (5)
    • ►  Jan (3)
  • ►  2010 (37)
    • ►  Dec (3)
    • ►  Nov (3)
    • ►  Oct (4)
    • ►  Sep (8)
    • ►  Aug (3)
    • ►  Jul (3)
    • ►  Jun (2)
    • ►  May (2)
    • ►  Apr (3)
    • ►  Mar (3)
    • ►  Feb (2)
    • ►  Jan (1)
  • ►  2009 (54)
    • ►  Dec (3)
    • ►  Nov (2)
    • ►  Oct (3)
    • ►  Sep (5)
    • ►  Aug (4)
    • ►  Jul (15)
    • ►  Jun (8)
    • ►  May (3)
    • ►  Apr (2)
    • ►  Feb (5)
    • ►  Jan (4)
  • ▼  2008 (75)
    • ►  Dec (6)
    • ►  Nov (8)
    • ►  Oct (9)
    • ►  Sep (8)
    • ▼  Aug (9)
      • Taming the Beast (a.k.a. how to test AJAX applicat...
      • Root Cause of Singletons
      • TotT: Sleeping != Synchronization
      • Where Have All the Singletons Gone?
      • Singletons are Pathological Liars
      • TotT: 100 and counting
      • TotT: A Matter of Black and White
      • Writing Testable Code
      • GTAC Attendance Application deadline Aug15
    • ►  Jul (9)
    • ►  Jun (6)
    • ►  May (6)
    • ►  Apr (4)
    • ►  Mar (4)
    • ►  Feb (4)
    • ►  Jan (2)
  • ►  2007 (41)
    • ►  Oct (6)
    • ►  Sep (5)
    • ►  Aug (3)
    • ►  Jul (2)
    • ►  Jun (2)
    • ►  May (2)
    • ►  Apr (7)
    • ►  Mar (5)
    • ►  Feb (5)
    • ►  Jan (4)

Feed

  • Google
  • Privacy
  • Terms