Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Why are Singletons evil?

 
Greg Charles
Sheriff
Posts: 2985
12
Firefox Browser IntelliJ IDE Java Mac Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From a thread in MD:

Pat Farrell wrote:
Greg Charles wrote:
1. GoF, Design Patterns (of course)


I really dislike this book. It has not aged well. About all anyone remembers from reading it is that singletons are great. This is not true. Singletons are evil.
Singletons ruin good design.


To me, Singleton isn't the most useful pattern, but I've never thought of it as evil. Could I get some examples?
 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are many, many reasons that Singletons are evil. So many I can't remember them all. But this thread will be a great place to jog my memory.

A] First and foremost, a singleton is just a global wad of memory. You use it to hold values and a few accessor methods that you can use everywhere. They tend to be used heavily and without thought. For the past 50+ years, good software engineering has aimed to provide information hiding and robust access, with the implementation left as a detail. When you have a global wad-o-data, you aren't hiding anything.

B] as a global wad-o-data, a singleton greatly increases coupling between modules and decreases cohesion. Again, this is directly in the opposite of the goals of software engineering over recent decades.

C] singletons make proper unit testing impossible. When a unit (class, etc.) relies on a global wad-o-badness, you can't test the unit without exercising the singleton. This means its no longer a unit test.

D] Java singletons are hard to setup properly. The runtime rules of the JVM make it difficult to get a singleton to be properly setup once, and only once. See IBM article on singleton double-check problem

E] Singletons may not be single in enterprise production systems. The J2EE class loader is allowed to load two or more instances of a class. Its a rare case, but it happens. When this happens, the Singleton class is not going to have one and only one instance.

F] singletons are un-needed. You can simply have a Factory class that returns the same instance over and over. It is trivial to implement, much easier to do than properly solving the double-check problem.



Google for "singletons considered harmful" and you will see tons of articles. Such as:
  • https://sites.google.com/site/steveyegge2/singleton-considered-stupid
  • http://www.object-oriented-security.org/lets-argue/singletons

  •  
    Jelle Klap
    Bartender
    Posts: 1951
    7
    Eclipse IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Singletons aren't evil. You just need to be very aware of the consequences of adopting the pattern, and their limitations i.e. when singletons aren't. Use it judiciously. That's really the biggest problem with this pattern: it's users. It's a very simple pattern to understand and apply whereas alternatives might not be so evident, and if all you have is a hammer everything looks like a nail.
     
    Paul Clapham
    Sheriff
    Pie
    Posts: 20958
    31
    Eclipse IDE Firefox Browser MySQL Database
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Pat Farrell wrote:D] Java singletons are hard to setup properly. The runtime rules of the JVM make it difficult to get a singleton to be properly setup once, and only once. See IBM article on singleton double-check problem


    One "evil" aspect of this is that, even several years after enums were introduced into the language and became the obvious simple way to create a singleton, people are still using the old, clumsy, fragile ways. I don't know what it is about programmers that they can't move on from old discredited techniques, but I'm seeing that sort of behaviour all over this forum. Singletons are just one example.
     
    Pat Farrell
    Rancher
    Posts: 4678
    7
    Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Paul Clapham wrote:I don't know what it is about programmers that they can't move on from old discredited techniques, but I'm seeing that sort of behaviour all over this forum. Singletons are just one example.


    And @bear is always going off on folks using 1990s technology (scriptlets) instead of proper EL in their JSP pages.
     
    Pat Farrell
    Rancher
    Posts: 4678
    7
    Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jelle Klap wrote:That's really the biggest problem with this pattern: it's users. It's a very simple pattern to understand and apply whereas alternatives might not be so evident, and if all you have is a hammer everything looks like a nail.


    I disagree. It looks like a very simple pattern to understand. And its widely used. But the implications on using it are not understood by the vast majority of programmers who use it.

    The use makes it impossible to have clean tests using great open source tools such as JUnit. The implications are that you don't unit test your code. This is a disaster for large scale systems. The current buzzwords in development, Test Driven Development, Agile, etc. are all based on very solid and thorough unit tests. Using Singletons breaks the basic concepts of these developments.

    Of bigger concern to me is that its trivially easy to use better approaches. There is no justification for using the singleton pattern, its no harder to use a better approach. Yet you see Singletons everywhere. You see questions about use of Singletons here on the Ranch all the time.
     
    Paul Clapham
    Sheriff
    Pie
    Posts: 20958
    31
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Pat Farrell wrote:
    Paul Clapham wrote:I don't know what it is about programmers that they can't move on from old discredited techniques, but I'm seeing that sort of behaviour all over this forum. Singletons are just one example.


    And @bear is always going off on folks using 1990s technology (scriptlets) instead of proper EL in their JSP pages.


    Exactly. We haven't had a good "What's wrong with using Vector anyway" thread for a while, maybe 1998 to 2012 is long enough for everybody to get used to the idea.
     
    Matthew Brown
    Bartender
    Posts: 4566
    8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I'd agree with Pat's points C, E and F. Which are good enough for me to avoid them. The other three are all about using singletons badly. If you banned every language feature or design concept that could be used badly then none of us would be programmers.

    Take D for example - it is absolutely trivial to avoid that problem. The simplest possible approach works fine - instantiate on declaration. It's when people try and complicate things that they run into trouble.
     
    Jelle Klap
    Bartender
    Posts: 1951
    7
    Eclipse IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Matthew Brown wrote:I'd agree with Pat's points C, E and F. Which are good enough for me to avoid them. The other three are all about using singletons badly. If you banned every language feature or design concept that could be used badly then none of us would be programmers.
    Take D for example - it is absolutely trivial to avoid that problem. The simplest possible approach works fine - instantiate on declaration. It's when people try and complicate things that they run into trouble.


    The Singleton pattern allows for lazy initialization, which the enum approach doesn't and the factory approach would have to implement it the same way. It's rarely actually needed, but then again it might be, and implementing it correctly doesn't require double-checked locking. There are many situations in which the Singelton approach is clearly not the way to go, or there are 'better' ways to go about implementing singleton behavior, but I still maintain that it can be a valid choice.
     
    Matthew Brown
    Bartender
    Posts: 4566
    8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jelle Klap wrote:The Singleton pattern allows for lazy initialization, which the enum approach doesn't and the factory approach would have to implement it the same way. It's rarely actually needed, but then again it might be, and implementing it correctly doesn't require double-checked locking. There are many situations in which the Singelton approach is clearly not the way to go, or there are 'better' ways to go about implementing singleton behavior, but I still maintain that it can be a valid choice.


    Jeff will probably be along in a minute to explain why he thinks lazy initialisation of a singleton is never required .
     
    Jelle Klap
    Bartender
    Posts: 1951
    7
    Eclipse IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The words never, always and evil are on my shit list
     
    Junilu Lacar
    Bartender
    Pie
    Posts: 7465
    50
    Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jelle Klap wrote:The words never, always and evil are on my shit list

    So is shit and all its derivatives on mine . I'm with you on this one. Anyone who uses the Spring Framework knowingly or unknowingly uses them, although some argue that Spring beans are not true Singletons.
     
    Matthew Brown
    Bartender
    Posts: 4566
    8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    But there's a difference, isn't there, between a singleton and the Singleton Pattern? That's one of the arguments against the Pattern - there are better ways of achieving it. Dependency injection with singleton scope is one.
     
    Pat Farrell
    Rancher
    Posts: 4678
    7
    Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Matthew Brown wrote: Dependency injection with singleton scope is one.

    Dependency injection means you never have to have a singleton. You just inject an object. None of the classes that use it care whether its a singleton or one of many instances. The injected object is no longer global, rather its explicit.
     
    Pat Farrell
    Rancher
    Posts: 4678
    7
    Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jelle Klap wrote: It's rarely actually needed, but then again it might be, and implementing it correctly doesn't require double-checked locking.


    If you follow the link to the referenced IBM paper, it clearly says that double-checked locking is not sufficient. It doesn't always work.

    One can therefore argue that nothing requires double-check locking, since double-check locking doesn't solve the fundamental problems.
     
    Matthew Brown
    Bartender
    Posts: 4566
    8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Pat Farrell wrote:Dependency injection means you never have to have a singleton. You just inject an object. None of the classes that use it care whether its a singleton or one of many instances. The injected object is no longer global, rather its explicit.

    That's part of my point: I'd differentiate "singleton" from "Singleton".
     
    Matthew Brown
    Bartender
    Posts: 4566
    8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Pat Farrell wrote:If you follow the link to the referenced IBM paper, it clearly says that double-checked locking is not sufficient. It doesn't always work.

    One can therefore argue that nothing requires double-check locking, since double-check locking doesn't solve the fundamental problems.

    I thought that paper was out of date because of changes to the memory model? Though I'd agree it's not the best solution.
     
    Pat Farrell
    Rancher
    Posts: 4678
    7
    Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Matthew Brown wrote:That's part of my point: I'd differentiate "singleton" from "Singleton".


    What is your difference? Having different meanings based on the capitalization of a word hurts communications. I'd use totally different words.

    I have no problems with software that makes one object and passes it around.

    I have serious problems with the singleton pattern, which makes a global glob of data and methods.
     
    Pat Farrell
    Rancher
    Posts: 4678
    7
    Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Matthew Brown wrote:I thought that paper was out of date because of changes to the memory model? Though I'd agree it's not the best solution.


    I don't attempt to keep up with subtle changes in the JVM. First because they are usually deep in the weeds. Second, because the JVM versions tend to stick around. I'm currently writing code for Java 6, because Java 7 is "too new" for some in the management chain.

    My argument is that using singletons is no longer a valid solution.
     
    Matthew Brown
    Bartender
    Posts: 4566
    8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Pat Farrell wrote:What is your difference? Having different meanings based on the capitalization of a word hurts communications. I'd use totally different words.


    But so does not standard usage. I'd argue that there is a long established meaning of the word "singleton" (before the Pattern was thought of), and it's the appropriate word to use. In the context of object-oriented software, it means a class with only one instance. The Singleton Pattern (note my first usage of differentiating by case did include the extra word as well) is one way of creating a singleton.

    But since I don't think we're disagreeing on anything very important, I'll stop there.
     
    Pat Farrell
    Rancher
    Posts: 4678
    7
    Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Matthew Brown wrote: I'd argue that there is a long established meaning of the word "singleton" (before the Pattern was thought of), and it's the appropriate word to use.


    Interesting. I never heard of a use of singleton in Computer Science before the GoF book. Could be that I just missed it.

    Of course, we had global wads-o-data in the 60s for COBOL and Fortran, and they were as evil then as they are in Singletons today. In Fortran, they were called "COMMON" and were a source of much suffering.
     
    Jayesh A Lalwani
    Rancher
    Posts: 2756
    32
    Eclipse IDE Spring Tomcat Server
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    [slight hijack] The most annoying thing about Singleton pattern is in any interview, when I ask:- "Which patterns are you familiar with?", the answer that I usually get is "Singleton pattern". Seriously?! C'mon! For once, someone say "factory" or heck, say "listener". Decorator, maybe? These patterns are more common in Java than Singleton

    Please no singleton!!
     
    Greg Charles
    Sheriff
    Posts: 2985
    12
    Firefox Browser IntelliJ IDE Java Mac Ruby
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jayesh A Lalwani wrote:[slight hijack] The most annoying thing about Singleton pattern is in any interview, when I ask:- "Which patterns are you familiar with?", the answer that I usually get is "Singleton pattern".


    Oh, man, that's what they were asking about? I just said paisley.
     
    Matthew Brown
    Bartender
    Posts: 4566
    8
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Pat Farrell wrote:Interesting. I never heard of a use of singleton in Computer Science before the GoF book. Could be that I just missed it.

    I wasn't thinking so much of computer science - my background's in mathematics. Which does possibly undermine my point a bit. Nothing to see here....
     
    Tim Holloway
    Saloon Keeper
    Pie
    Posts: 18094
    48
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Oh, man, that's what they were asking about? I just said paisley.


    I was going for a houndstooth myself. Or the clan plaid. My family has a nice bluish-green plaid.

    The problem with singletons is that they often end up needing to be doubletons. Or tripletons, or...

    Better a singleton than class methods, though. Sooner or later I always end up reworking them because I need to stop passing around large quantities of what would otherwise be instance data.

     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic