by Miško Hevery
So you join a new project, which has an extensive mature code base. Your new lead asks you to implement a new feature, and, as a good developer, you start by writing a test. But since you are new to the project, you do a lot of exploratory “What happens if I execute this method” tests. You start by writing this:
testCreditCardCharge() { CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); }
This code:
- Only works when you run as part of the suite.
- When run in isolation, throws NullPointerException.
- When you get your credit card bill, you are out $100 for every time the test runs.
Now, I want to focus on the last point. How in the world did the test cause an actual charge on my credit card? Charging a credit card is not easy. The test needs to talk to a third party credit card web-service. It needs to know the URL for the web-service. It needs to authenticate, pass the credentials, and identify who the merchant is. None of this information is present in the test. Worse yet, since I don’t even know where that information is present, how do I mock out the external dependencies so that every run does not result in $100 actually being charged? And as a new developer, how was I supposed to know that what I was about to do was going to result in me being $100 poorer? That is “Spooky action at a distance!”
But why do I get NullPointerException in isolation while the test works fine when run as part of the suite? And how do I fix it? Short of digging through lots of source code, you go and ask the more senior and wiser people on the project. After a lot of digging, you learn that you need to initialize the CreditCardProcessor.
testCreditCardCharge() { CreditCardProcessor.init(); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); }
You run the test again; still no success, and you get a different exception. Again, you chat with the senior and wiser members of the project. Someone tells you that the CreditCardProcessor needs an OfflineQueue to run.
testCreditCardCharge() { OfflineQueue.init(); CreditCardProcessor.init(); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); }
Excited, you run the test again: nothing. Yet another exception. You go in search of answers and come back with the knowledge that the Database needs to be initialized in order for the Queue to store the data.
testCreditCardCharge() { Database.init(); OfflineQueue.init(); CreditCardProcessor.init(); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); }
Finally, the test passes in isolation, and again you are out $100. (Chances are that the test will now fail in the suite, so you will have to surround your initialization logic with “if not initialized then initialize” code.)
The problem is that the APIs are pathological liars. The credit card pretends that you can just instantiate it and call the charge method. But secretly, it collaborates with the CreditCardProcessor. The CreditCardProcessor API says that it can be initialized in isolation, but in reality, it needs the OfflineQueue. The OflineQueue needs the database. To the developers who wrote this code, it is obvious that the CreditCard needs the CreditCardProcessor. They wrote the code that way. But to anyone new on the project, this is a total mystery, and it hinders the learning curve.
But there is more! When I see the code above, as far as I can tell, the three init statements and the credit card instantiation are independent. They can happen in any order. So when I am re-factoring code, it is likely that I will move and rearrange the order as a side-effect of cleaning up something else. I could easily end up with something like this:
testCreditCardCharge() { CreditCardProcessor.init(); OfflineQueue.init(); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); Database.init(); }
The code just stopped working, but I had no way to knowing that ahead of time. Most developers would be able to guess that these statements are related in this simple example, but on a real project, the initialization code is usually spread over many classes, and you might very well initialize hundreds of objects. The exact order of initialization becomes a mystery.
How do we fix that? Easy! Have the API declare the dependency!
testCreditCardCharge() { Database db = Database(); OfflineQueue q = OfflineQueue(db); CreditCardProcessor ccp = new CreditCardProcessor(q); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(ccp, 100); }
Since the CreditCard charge method declares that it needs a CreditCardProcessor, I don’t have to go ask anyone about that. The code will simply not compile without it. I have a clear hint that I need to instantiate a CreditCardProcessor. When I try to instantiate the CreditCardProcessor, I am faced with supplying an OfflineQueue. In turn, when trying to instantiate the OfflineQueue, I need to create a Database. The order of instantiation is clear! Not only is it clear, but it is impossible to place the statements in the wrong order, as the code will not compile. Finally, explicit reference passing makes all of the objects subject to garbage collection at the end of the test; therefore, this test can not cause any other test to fail when run in the suite.
The best benefit is that now, you have seams where you can mock out the collaborators so that you don’t keep getting charged $100 each time you run the test. You even have choices. You can mock out CreditCardProcessor, or you can use a real CreditCardProcessor and mock out OfflineQueue, and so on.
Singletons are nothing more than global state. Global state makes it so your objects can secretly get hold of things which are not declared in their APIs, and, as a result, Singletons make your APIs into pathological liars.
Think of it another way. You can live in a society where everyone (every class) declares who their friends (collaborators) are. If I know that Joe knows Mary but neither Mary nor Joe knows Tim, then it is safe for me to assume that if I give some information to Joe he may give it to Mary, but under no circumstances will Tim get hold of it. Now, imagine that everyone (every class) declares some of their friends (collaborators), but other friends (collaborators which are singletons) are kept secret. Now you are left wondering how in the world did Tim got hold of the information you gave to Joe.
Here is the interesting part. If you are the person who built the relationships (code) originally, you know the true dependencies, but anyone who comes after you is baffled, since the friends which are declared are not the sole friends of objects, and information flows in some secret paths which are not clear to you. You live in a society full of liars.
[ Follow up: Where Have All the Singletons Gone ]
[ Follow up: Root Cause of Singletons ]
77 responses so far ↓
Dear Misko,
Thank you for the informative article. I like the idea about doing dependency check during compile time. I am sure this will save a lot of time while testing.
I have one question though. The solution does not call offlinequeue’s Init method. I think we have moved the logic contained within Init into the constructor of offlinequeue.
My mind is forever torn between what needs to go into the constructor and what needs to go into the Init method.
Can you suggest me some ideas as to what and how much can reside with a constructor.
What questions can I ask to decide to determine what goes in a constructor and what goes in a Init method?
I am an avid follower of your blog. I really liked this particular one becuase I understood if fully. I think I have been a newbie in a new team too often. Your ideas are very sound and practical.
@Andy:
I will respond with my opinion about your question. Misko will likely chime in here soon too.
Rephrasing the question, to make sure I understand you:
Moving from using OfflineQueue.init()
To using new OfflineQueue(… dependencies …)
Where does the initialization logic go, if not in the OfflineQueue constructor?
There are two separate responsibilities: OfflineQueue initialization, and whatever else it is designed for (the business use). The constructor is used to instantiate the queue, but there is no reason it should do the initialization. That would be a mixing of concerns, and you’d be forced to initialize in the same way for tests. (You can’t override a constructor, and IMHO a separate constructor “just for testing” is a code smell.)
Solution:
Create a factory or builder or use a Guice provider to do the construction and initialization. Then whenever you need a queue, it will be fully initialized when you get it injected, or call the getter/builder method on the factory/builder/provider.
Cheers, and thanks for the questions
Following Jonathan’s comment a bit, don’t even build a factory – use an Inversion of Control container to do Dependency Injection, and let the container be the glue-code for you. If there’s intialization, then use a container that has a lifecycle system that allows you to make an “init()” method which is called by the container.
Actually, I’d probably reverse this line to
ccp.chargePurchaseToCard(100,c); since the logic for purchasing will be in the processor anyway, not the card. Cards don’t process anything.
Well looks like there is nothing for me to say to Andy, as Jonathan and Christian advice is right on. In general the less work in constructor the better. My personal opinion is that constructor should only do field assignments and nothing more. (Hmm that would make a good blog post)
Top 10 things which make your code hard to test | Miško Hevery // Aug 18, 2008 at 11:45 am
[...] Singletons (global state in sheep’s clothing): It amazes me that many developers will agree that global state is bad yet their code is full of singletons. (Singletons which enforce their own singletoness through private constructor and a global instance variable) The core of the issue is that the global instance variables have transitive property! All of the internal objects of the singleton are global as well (and the internals of those objects are global as well… recursively). Singletons are by far the most subtle and insidious thing in unit-testing. I will post more blogs on this topic later as I am sure it will create comments from both sides. (see: Singletons are Pathological Lairs) [...]
> Singletons are nothing more than global state.
Well yeah.
The issue, though, isn’t that singletons are liars, it’s that the singletons you were *using* were liars, and you said it yourself: “The problem is that the APIs are pathological liars.”
Well singletons allowed the CreditCard object to get a hold of the CreditCardProcessor. If CreditCardProcessor was not globally accessible, than CreditCard would have no choice than to ask for it in its constructor or in a parameter. I don’t see how “my” singletons are any different from “their” singletons. In all cases the result is that API ends up hiding true dependencies. So singletons enable the API to lie.
Where Have All the Singletons Gone? | Miško Hevery // Aug 21, 2008 at 11:48 am
[...] Singletons are Pathological Liars we discussed the problems of having singletons in your code. Let’s build on that and answer [...]
> So singletons enable the API to lie.
So singletons aren’t liars, APIs are. We agree.
If you have singletons and use them than your APIs are automatically liars.
If you don’t have singletons it is impossible for the APIs to lie.
I don’t see how you can can have singletons and not have the APIs lie.
If you want to split hairs, than yes APIs are the ones who are actually doing the lying, but it is the singletons which force them. So I am putting the blame at the source not at the messenger.
“Singleton” — you keep using that word; I do not think it means what you think it means. A singleton is a class with at most one instance, and this invariant is maintained using a static factory method (or function). Objects which use the singleton don’t need to behave any differently, and more importantly, simply using the singleton pattern does not create the weird kind of hidden dependencies you have described.
Here’s what the original example would actually look like using the singleton pattern:
testCreditCardCharge() {
CreditCard c = new CreditCard(
“1234 5678 9012 3456″, 5, 2008);
c.charge(CreditCardProcessor.getInstance(), 100);
}
Internally, CreditCardProcessor.getInstance() would have initialized the processor using Database.getInstance(), OfflineQueue.getInstance(), etc. In a unit test, you would just substitute in TestCreditCardProcessor.getInstance() or something similar instead.
“Singleton” — you keep using that word; I do not think it means what you think it means. A singleton is just a class with at most one instance, and this invariant is maintained using a static factory method (or function). Objects which use the singleton don’t need to behave any differently, and more importantly, simply using the singleton pattern does not create the weird kind of hidden dependencies you have described.
Here’s what the original example would actually look like using the singleton pattern:
testCreditCardCharge() {
CreditCard c = new CreditCard(
“1234 5678 9012 3456″, 5, 2008);
c.charge(CreditCardProcessor.getInstance(), 100);
}
Internally, CreditCardProcessor.getInstance() would have initialized the processor using Database.getInstance(), OfflineQueue.getInstance(), etc. In a unit test, you would just substitute in TestCreditCardProcessor.getInstance() or something similar instead.
Seems to me he violated the cardinal rule of testing, which of course is:
**Always check your environment settings first**
You shouldn’t be running any code what so ever until after you check to see if your code is pointing to a production or test environment.
Oh, and I love these comments.
Don’t use a singleton, “Create a factory or builder or use a Guice provider to do the construction and initialization.”
No wait, “use an Inversion of Control container to do Dependency Injection, and let the container be the glue-code for you”
Of course neither of these actually address the real problem, being the configuration management for that project sucks. Fix it, and it doesn’t matter how you grab your dependencies.
**Configuration is global, deal with it.**
Adrian said the first sensible thing.
Improperly implemented patterns are the actual problem.
And having multiple functions (one for constructing and another for initializing) is not a blanket rule either. It’s pointless to have 2 function calls when 1 function call can execute the same code and have the same side effects.
If lazy loading is the reason for multiple functions, that can easily be handled within the implemention of the object.
If error isolation is the reason for multiple functions, then that means the test is testing multiple units, which means it’s then a “suite” and not a “unit”.
This article really should be able how not to use singletons or how to properly implement a singleton or how not to use static classes, etc…
I had some of the same thoughts that Adrian did. It seems the real problem here is the use of static factory methods from within the class, instead of being passed in as arguments. This is a problem regardless of whether the class is a singleton.
Root Cause of Singletons | Miško Hevery // Aug 25, 2008 at 10:01 pm
[...] I have gotten lots of love/hate mail on the Singletons are Pathological Liars and Where Have All the Singletons Gone I feel obliged to to do some root cause [...]
My main() Method Is Better Than Yours | Miško Hevery // Aug 29, 2008 at 6:21 pm
[...] (I know we can fight static with static, but we already said that global state is bad here, here and here). The reason we can’t test this is that the moment you execute the main method the [...]
If we break down your suggestion you have essentially hidden:
a(); b(); c(); into abc();
Which is great because it means the new guy can’t screw up the order of abc() but how does the author of abc() know the order? Maybe with misko’s logic that info should be contained in the API which you’ve got to agree is better in the long term?
Where Have all the “new” Operators Gone | Miško Hevery // Sep 10, 2008 at 10:30 am
[...] here are few thoughts on my love/hate of Singletons (mentioned here and here) First a little review of singletons. A singleton with a lower case ’s’ is a [...]
Shameless Promotion for my Shared Items « Better Software. Better Science. Better Sense. // Sep 17, 2008 at 8:28 am
[...] Singletons are Pathological Liars. Miško Hevery has been writing the clearest (bestest!) introductions to designing for unit testing that I have seen. They’re not really introductions so much as they are motivators. [...]
Application Wiring on Auto-Pilot | Miško Hevery // Sep 24, 2008 at 10:38 am
[...] as manage object lifetimes, enforce singletons (in a good way, see: Root Cause of Singletons and Singletons are Pathological Liars) and manage different configurations of your application such as production [...]
Why is global bad? Yeah, I know what your are thinking, and no, I am not joking. There are certain languages like JS which are quite powerful and yet have limited ability to comeup with walls (modularity).
Global is bad because:
a. It causes namespace conflict
b. It exposes the state in a unwarranted fashion
When it comes to Singletons
a. The explicit OO way of calling them, prevents the conflicts, so point a. is not an issue
b. Singletons without state are (like factories) are not a problem. Singletons with state can again fall in two categories, those which are immutable or write once and read many (config/property files). These are not bad. Mutable Singletons, which are kind of reference holders are the ones which you are speaking of.
Now if they are designed to act as application cache, you may see a lack of adequate cohesion. So what do we do! Using the pathelogical lies analogy, hide the unpleasant details, in private methods or in interfacing Adaptors (IOC). Make sure that these kinds of singletons are restricted to above sections of code and for the rest of application they become person-nongrata. Finally when you test the application, you won’t see the singletons. Not fool proof, but just makes it a wee bit difficult to accidentally modify things.
If we are exposing state of instance to Singletons in any other way, it is a bad OO design.
Quoting Dalai Lama, “Know your rules well, so that you can break them”. Share your thoughts as well, I have stumbled upon your blog and it was a delight so far.
“In general the less work in constructor the better. My personal opinion is that constructor should only do field assignments and nothing more. (Hmm that would make a good blog post)”
That’s an interesting opinion. I’ve always seen it as an anti-pattern to have “init()” methods. Objects have constructors to initialize themselves.
Having a constructor properly initialize the object prevents a whole set of errors – you can never use the object without having it initialized properly, because it simply won’t exist before.
Even if you use a IoC framework that automagically will do the init call for you, this further obscures the meaning of the code – your programming language has a feature to enforce proper initialization, so why not rely on it? With your words, the API of those objects lies – they have a constructor to initialize them, but in reality they rely on different code to do the actual initialization.
Also, programming languages usually enforce the proper order of initialization of superclasses, which doesn’t really work well with IoC and “init()” methods.
In some cases, lazy loading is probably useful or even necessary, but I think you should always thrive to limit it’s effects.
Singleton I love you, but you're bringing me down | // Coding Without Comments // Oct 8, 2008 at 7:58 pm
[...] “objects can secretly get hold of things which are not declared in their APIs, and, as a result, Singletons make your APIs into pathological liars.” Basically, when objects use Singletons they hide their [...]
Delicious 081006 ~ 081012 | ur-ban.com - Richard Hart // Oct 13, 2008 at 4:38 am
[...] Singletons are Pathological Liars [...]
Great article, but I’ve got a little question.
In your last example you create an instance of Database. But let’s say we NEED a global (in the sense of every class should have the opportunity to access it) database interface.
It would not be effective to instanciate a connection everytime data is needed. So where and how to place and instanciate the Database?
I only see two ways to handle such a “glboal” database connection: The first IS to use somwhere and somehow static declarations. The other way is to create a connection at program startup and pass it further and further. This means that there are cases in which the connection handle is passed (and possibly saved in a class variable) just in order to pass it further.
Wouldn’t this be a waste of space and speed and (more important) end in an unnecessary bloated code?
I don’t know if I am wrong, but for me it seems that to use static code or not isn’t a definite decision but a compromise.
Therefore I wonder where to draw the line?
@okoman
I am trying to answer your question in here: http://misko.hevery.com/2008/10/21/dependency-injection-myth-reference-passing/
Dependency Injection Myth: Reference Passing | Miško Hevery // Oct 21, 2008 at 2:11 pm
[...] the calls to Database, we did not even know by looking at the API that Database is involved. (see Singletons are Pathological Lairs) I hope everyone would agree that this change of explicitly passing in a Database reference greatly [...]
Using Hibernate UserType’s for oddly formatted legacy tables (with tests) at JAW Speak // Nov 9, 2008 at 11:23 pm
[...] Read more at a thread over on the Spring Forums about the lack of DI. If you have any doubts of Singletons and Statics as the worst thing ever, please stand up and argue your [...]
My Unified Theory of Bugs | Miško Hevery // Nov 17, 2008 at 4:37 pm
[...] Injection –> makes wiring explicit (unlike singletons, globals or service [...]
Think louder » DotNet Testability Explorer // Dec 2, 2008 at 8:58 pm
[...] Testing on CAB的内部培训项目期间,阅读了Miško Hevery的一系列文章,他目前在Google担任敏捷教练。我对他own的一个项目- Testability [...]
Static Methods are Death to Testability // Dec 15, 2008 at 7:44 am
[...] have already covered that global state is bad and how it makes your application hard to understand. If your application has no global state than all of the input for your static method must come [...]
tartley.com » Blog Archive » Expert Python Programming // Jan 11, 2009 at 3:59 pm
[...] Tarek never explicitly says this, to some extent it is born out by this chapter. Trivial (and much-maligned) ideas like the Singleton, after a page or two of alternate implementations, boil down to simply [...]
Mobile Talk » Creating One Location Manager For Multiple Activities // Feb 25, 2009 at 9:12 pm
[...] approach would be to use some kind of Singleton, but I don’t like singletons, this is a good link explaining why, and singleton wouldn’t really resolved my problem: if lets say activity A had [...]
AS3 Dependency Injection and [Autowire] « shaun smith // Mar 13, 2009 at 6:33 am
[...] you could use a Singleton to hang all your objects on. That would not be cool: link, link, [...]
Stupid evil cancerous liars, I hate you! « Luke Halliwell’s Weblog // Apr 23, 2009 at 4:51 am
[...] knows singletons are bad, right? I mean, they’re stupid, they’re evil, they’re pathological liars, they cause cancer, this guy hates them, and they bring people [...]
Another Architectural Framework, But Why? « shaun smith // Apr 29, 2009 at 5:47 am
[...] standard Singleton implementation (that static getInstance method) is severely flawed. Unless you are writing device [...]
Nice article. I found the example very interesting. I know we have some of these problems in our code. Now hopefully I’ll be able to apply this in practice.
andré vendramini » Blog Archive » Singleton // Jul 14, 2009 at 7:38 pm
[...] http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/ [...]
Tim Cinel » Blog Archive » 2009-08-11 - My Daily Summary // Aug 11, 2009 at 5:04 pm
[...] Bookmarked a link on Delicious. Singletons are Pathological Liars [...]
www.christian-rehn.de » Warum Singletons bööse sind // Sep 3, 2009 at 9:17 am
[...] Singletons are Pathological Liars: ein extremes Beispiel, wie man Singletons nicht verwenden sollte. [...]
Unit testing and the big dependency graph « Melle Koning Blog // Dec 24, 2009 at 4:53 pm
[...] of all I want you to have a look at Singletons are pathelogical liars, because that is one of the challenges we curently have in our own code base as all our [...]
Meta Matters | Shopzilla Tech Blog // Jan 28, 2010 at 4:50 pm
[...] very similar point to the above is that objects hide parts of their API (as also described here). There is in fact a requirement on the product search implementation that it sets the ThreadLocal, [...]
I certainly agree that the hidden dependencies are bad, but I’ll echo those who question how this is really tied to singletons. I could create the same problem without using singletons: For example, I could have a “final static QueueManager” somewhere that I simply expect to only be created once without any singleton pattern to enforce this. Or I could create a new QueueManager each time I create a CreditCard object. Or numerous other ways.
On the other hand, just because someone defines a singleton doesn’t mean it must be abused in this manner.
Singletons don’t kill transparent dependency. Bad programmers kill transparent dependency.
@Jay,
how is “final static QueueManager” not a singleton? Could you make two of these? no, so it is a singleton.
If the singleton class is a “utility class” (e.g. FileUtils, StringUtils, etc.), and has no state, then I would say it’s okay. Such a class is not a liar, per se, because there is no unexpected state change or dependency.
@Luke,
correct, the issue is Global Mutable state. Constants are OK.
FLEX 4 : Dependency Injection Using Parsley at CodesOfMyLife // Mar 14, 2011 at 12:53 pm
[...] the code harder to maintain and test and its also referred to as ‘anti-pattern’ now [4][5][6]. On the other hand the creation of instances is handled by DI container and the dependent [...]
A singleton is not an anti-pattern, provided it is designed correctly.
A public init() method on a singleton object is 100% an anti-pattern, period, and a potential Thread-safety minefield; just don’t do it!
A getInstance() method is far safer, because it can provide a completely isolated instance of a class (not necessarily the same class).
A singleton should be treated as a factory e.g. a JNDI lookup to provide a DataSource instance, and the DataSource to providing a Connection instance. Admittedly even the DataSource design is stupidly flawed, because it has setters rather than an optional parameters object for the getConnection() methods.
@Infernoz,
I am afraid, that you have missed my point with respect to Singletons. Singletons are global variables, and hence have all the problems associated with them. Global variables are greatly discouraged in programing.
Interesting read for a Friday morning
I like the comparison between time and money… You can spend hours figuring out what some code does, and still not get the whole thing figured out.
Good tip for future coding! Yeah, I admit, I used to be happy when the code just did what I wanted it to do, but now it gets more and more about doing things right
Awesome article and very true. I never use singletons since they are same as global variables, which are not good. However, I use different approach: Your code would look like this:
$api = new TestingSuite();
$api->add(‘CreditCardProcessor_Testing’);
$api->add(‘DB’)->connect(‘testing’);
$api->add(‘CreditCard’)->charge(123);
method add sets up link between new object, api and parent. So if i do have to make object rely on each other, at least the suite can line up a substitutes. What’s also interesting, I can initialize multiple API classes at the same time and they would behave without conflicting with each other.
In my definition singleton can only be added to “parent” once. It can exist in multiple API instances just fine.
Thanks again for article!
Revolução Java - Artigos, Tutoriais, Livros e Dicas atualizadas sobre o Mundo Java! // May 30, 2011 at 7:58 am
[...] design patterns, I think Singleton has the worst reputation. They have been called “evil,” “liars” and even “stupid,” and for good [...]
Understanding the Robotlegs Injector: The Robots are Running the Factory | RIA RockStars // May 31, 2011 at 7:02 am
[...] the same Object and know it was the same Object. But it turns out that this has a number of problems. The goal of the Singleton pattern was to make sure one instance of an object is created in the [...]
Technical Presentations and Understanding the Little Things | DaedTech // Jun 16, 2011 at 12:52 pm
[...] presentation, in particular, that struck me as effective had to do with singletons (he calls them pathological liars). In this talk (and in the linked post), he told a story about setting up a test for instantiating [...]
This is not only a singleton problem, but also an IOC issue. That’s why I refuse to use IOC in my applications.
@Michel,
IOC, solves this problem by removing global state. So I don’t think we are talking about the same thing.
Did you really use your real-life credit card details to test software?! I’ve only read a few paragraphs into this post (and will continue after I finish ranting) but that seems like a silly thing to do and $100 well spent on a life-lesson that you won’t forget any time soon!
@goob,
never let truth get in the way of a good story.
The purpose of the Singleton pattern is to allow only once instance of a class. ‘Merely’ declaring a global instance of a class doesn’t do that. Another global instance could still be created.
While global variables are generally bad because of the scoping issue, if an attribute could be added to a global variable to prevent other instances of the variable’s type, it would be like a Singleton, but it would only be bad if the global type wasn’t scoped, such as class methods (and classes in namespaces). (Of course, Class names are global too unless they’re in a namespace, and there is nothing to prevent putting any class, including a Singleton class, in a namespace).
In this case, by design, a single instance of a class is desired, and a Singleton is the only way to do this. (That’s by definition – any pattern that does this is a type of Singleton pattern).
Now, a good question is which Singleton pattern is best. Scott Meyer’s, and others, have addresses this issue.
By the way, if the point about being global is that a Singleton can be included in any file and used anywhere in a program, that’s true, but only bad if misused. The Singleton pattern is not inherently bad, it’s misuse is bad.
I should point out that the same issue exists with class instances. They can be inappropriately passed to constructors violating certain design guidelines. Bad object oriented design is always possible! (There are more wrong things to do than right ones!).
However, the point about being global is off the mark, because in that case, it’s the point! If you only want one instance of a class, then clearly any client that needs an instance of that class has to use that one existing Singleton instance. Whether that one instance is used inappropriately is a different matter.
Are singletons pathalogical liars? | Davelog // Dec 31, 2011 at 4:48 pm
[...] Miško Hevery thinks so: Singletons are Pathological Liars. [...]
Understanding Singletons // Feb 7, 2012 at 7:30 pm
[...] data are now using that updated value. Misko Hevery has written an amusing post on this topic here titled “Singletons are Pathological [...]
What is the best practice – singleton & components | free icons download // Feb 20, 2012 at 7:59 pm
[...] Singleton is never a good practice http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars . However, I think even developers who are highly committed to clean code will bend on this [...]
Singletons são mentirosos compulsivos » Henrique Barcelos - Webdeveloper - Blog // Feb 22, 2012 at 9:04 pm
[...] do artigo original Singletons are patological liars de Misko [...]
Tidbit: Singleton | No Pity for the Masses // Mar 14, 2012 at 9:10 pm
[...] had sitting in my toolbox for many years. More than a few developers consider Singleton Patterns evil, myself included. In a nut shell, by allowing any class to call the Singleton you destroy the OOP [...]
Thanks for this informative article. I will be sure to refrain from lying to my clients in the future.
This is probably the best article I have come across so far. Its describing singleton in very much depth.
Thanks for your article.
Hi Misko,
). It was a real head turner !
Thanks for such a great article. I am just venturing in the world of OO PHP. I met your article at just the right time (guess it’s not too costly to make corrections to my classes
Thanks for such a beautiful article.
You’re not really arguing against a singleton here, you’re arguing in favor of explicit dependencies, which can be accomplished using a singleton:
public class Singleton
{
private Singleton instance;
Private IDependency dependency;
private Singleton() {};
public static getInstance(IDependency dependency) {
if (instance == null) {
instance = new Singleton();
}
instance.setDependency(dependency);
return instance;
}
Which is not to say singletons are always a good idea. The real issue with singletons, is you don’t know if the state of a singleton has been changed (or configured) elsewhere.
The example above is fully mockable and forces explicit dependencies, but it doesn’t prevent dependency from being set outside the current context. Sometimes that is good, as with global configuration, but often it can be surprising.
The fundamentals of automated testing : Atomic | Mark's Devblog // Nov 1, 2012 at 10:50 pm
[...] … then ModelLoader has an implicit dependency on the MemoryManager. It’s implicit because there is nothing in the public API to say that this static class MemoryManager is used, let alone that it must be initialised if we want to use the ModelLoader. As Misko says, Singletons are pathological liars. [...]
One Singleton to Rule Them All | DaedTech // Nov 26, 2012 at 12:20 am
[...] Misko Hevery: Singletons are Pathological Liars [...]
I had never thought on the evil side of using singletons. This article give me a very good insight and intuition to better understand “dependency injection” stuff.
Thank you.
Man, i’ve never enjoyed reading about singletons as much as i’ve encountered in this blog. Not only is it clear now, but i will never in my life use another singleton.
If Singletons are bad then why is a Service Container good? - Tech Forum Network // Jun 14, 2013 at 10:50 pm
[...] We all know how bad Singletons are because they hide dependencies and for other reasons. [...]
Leave a Comment