Sunday, December 28. 2008
How to get a Singleton right
Books, tutorials and other design pattern featuring articles often tend to present the Singleton Design Pattern as the first one. This is for two reasons:
However, the Singleton design pattern is fundamentally flawed. This is nothing new and is discussed amongst developers since some years now (just search for "evil singleton"). The Singleton violates several rules of good object oriented design. Code using the Singleton class depends on that class. It is not usable without this class, which in turn makes the client code hard to test. The client code is not programmed against an interface but against a concrete class, though promoting tight coupling between the client and the Singleton, instead of the desired loose coupling. Additionally, classes implementing the Singleton pattern itself are hard to test. Singleton just replaces a global variable and hides it in a class - the global state stays in your application. So, when everybody agrees that global state is bad and that its appearance as Singleton implementations does not make the code any better, why is the Singleton design pattern so often used then?
To answer this question I want to take a step back and take a look at classes implemented as a Singleton. If you look at a typical Singleton implementation, you can divide the methods in such a class into two categories: those that belong to the business logic of this class, and those responsible for creation and access to the single instance of the class. As we can see, these are two different responsibilities. In object-oriented school we learned that a class should have just one responsibility, but nevertheless we make use of a design pattern that mixes two different responsibilities into one class. Why should the class decide how much instances of it shall be created in the application? Actually, the class should not know at all how much instances of it are floating around. It is simply not the responsibility of the class. It should take care that the business logic in the class is performed to the best of its knowledge, and from my point of view a class has all hands full with this task.
On the other hand it is perfectly valid to restrict the amount of instances of a class. And naturally we want to prevent other programmers who use our code to circumvent any such restrictions. Still, why should another programmer care about how many instances of a certain class are floating around in an application (besides performance reasons)? The other programmer should just declare in his code "I need an instance of Logger, and my code will not work without it, and boy I don't give a damn how much instances of Logger are allowed, just give me one!". Let's get back to responsibilities of a class: a class is responsible for the business logic it contains, and it is responsible to declare the stuff it requires to perform this business logic correctly. By using a Singleton class it declares this dependency in a hidden place. It is not possible from its API to tell that the class depends on another class, if not otherwise stated in some docs. Additionally it should never care how the classes it depends on are created. To sum it up: a class should declare its dependencies explicitly, and this is just done by defining in the constructor "I need this to work properly, and if you do not give me this you will not get an instance of me". Finally some code to illustrate this: Bad:
class Foo {
protected $logger;
public function __construct() {
$this->logger = Logger::getInstance();
}
...
}
Good:
class Foo {
protected $logger;
public function __construct(Logger $logger) {
$this->logger = $logger;
}
...
}
Here, the second example clearly states that Foo needs an instance of Logger in order to be created. Provided there are proper doc comments (left out to leave the example code short) the API documentation will tell users of Foo that they need Logger in order to get a Foo. Additionally, Foo will be much easier to test because one can inject a mock object instead of a concrete class. As you may have guessed, there is already a name for this style: dependency injection. The shortest explanation for this term might be this one: "Dependency injection means that a class gets the classes it depends on injected as parameters via its constructor or setter methods". When adhering to the dependency injection principle, you can separate your classes into two categories: those which contain just the business logic, and those which are responsible for creating instances of other classes and stacking them together.* (We've had this before, didn't we?). The good thing about this is that you may stack the business logic classes together in another way and receive a different behaviour - without changing any of the business logic classes at all. But how do we make sure now that there is only one instance of a certain class? Well, this is the responsibility of the classes that are responsible for creating instances. There you can create an instance of Logger and everywhere another class needs a Logger you pass it this instance. Now you have a singleton** as well, but without the penalty that comes with the Singleton design pattern. One more benefit: if you suddenly detect you need more than one instance of Logger you do not need to change Logger and the classes using Logger now. Just change the code responsible for constructing and stacking objects. Admittedly, coding this way creates a lot of boilerplate code (which is the code constructing and stacking objects). Writing such boilerplate code is really boring, gets tedious and does not make fun at all. This is a point where a dependency injection framework may help. But that is a story for another day. One last point. Developers introduced to the topic of dependency injection are often intrigued by the idea but mostly ask the same question: Do I need to pass all my objects required in a deeper layer to the upper layer just so that the upper layer may pass them to its underlaying layer? The short answer to this: no. At least not when implemented correctly. Let's take a house for example. A house has a door, and the door has a lock. When the house requires a lock in order to pass it to the door the design is messed up. The house should just require a door. Whether the door requires a lock or not is total irrelevant to the house. An implementation could look like this:
class House {
protected $door;
public function __construct(Door $door) {
$this->door = $door;
}
...
}
class Door {
protected $lock;
public function __construct(Lock $lock) {
$this->lock = $lock;
}
...
}
See? The house never needs to know about locks - it just knows about doors. If at all it needs something to do with locks this is exposed as methods on the Door class. (Actually, Door should be an interface, but for this short example it is ok to be a class.) To answer the question from above: the Singleton Design pattern is used so often because the rest of the code has flaws in its design, it does not separate business logic and instance creation logic right. It is perfectly valid to limit the amount of instances of a class, but to do it right via a single instance in the creation logic the rest of the application must be designed with dependency injection in mind. One could argue that code needs to be refactored as long as there is a Singleton in it. * An exception to this are classes containing values and data only but no logic - those might be created by the business logic classes using one of the other creational design patterns. ** One could call this the "small singleton" - denoted here with a small s contrary to the design pattern, which has a big S. ![]() Trackbacks
Trackback specific URI for this entry
No Trackbacks
![]() Comments
Display comments as
(Linear | Threaded)
I love such comments. They are so... clever and helpful.
Good reading. At least, it's good to see some php developers are still thinking (take a look at http://phpadvent.org/2008/php-is-not-java-by-luke-welling - Oh my...)
What are your feelings on the "Registry" design pattern?
> What are your feelings on the "Registry" design pattern?
I think it's worth an own blog post (but not that long like this one), stay tuned.
I wanted to second that, when I read the intro to your blog entry I thought - sounds like a registry.
I wouldn't say the Singleton is "evil" however I do think that it's the single most design pattern that has been misunderstood and abused.
The problem is that the Singleton is simple in it's architecture compared to other more complex design patterns, such as Visitor for example. The other problem is that the Singleton is used through out a domain, in the lower layers of an application, where as it should only really be used in the higher layers... Remember that the layer above is allowed to know about the layer immediately below it, however the lower layer has know knowledge of the layer above it? That very practice is more or less lost with todays web developers, both at the application level and at the framework level. So is the Singleton evil? No, I don't think so but it's as much to do with badly designed layering, to blame.
I would not say the Singleton is necessary evil. It may have its places, especially if you have a lot of legacy code the introduction of a Singleton might be a good idea, as it solves a problem in this moment much faster then refactoring the whole code to adhere to the dependeny injection principle. But if I would start a new application from scratch today: avoid it.
This reminds me of a Google Tech Talk http://www.youtube.com/watch?v=-FRm3VPhseI
I confess to have drawn some inspirations from this talk.
I think this entire blog post (and mine along similar lines recently (http://www.garfieldtech.com/blog/dependency-injection)) can be summed up as:
"Singletons aren't inherently evil, but the singletonness should be enforced by a factory, not the class itself, and a class should not be its own factory."
I'm not really understand what you wanted to say. If the responsibility of limiting the number of a class's instances is at the Factory class, then how in haven will you ensure that the factory class will return the same instance when the Factory can be instantiated more then once?
For me it seems that using a Factory for this is just pushing the responsibility up(down) a level, but it will not help you avoiding the Singleton pattern, and this is because global variables are not invented just to support wrongly structured code. They have their place in programming. What we should avoid is messing global name space, which can be accomplished by coupling the "global behaviour" into packages and classes of their own. A class can have more than 1 responsibility, (of course it is not recommended), if it makes sense. And this "sense" is really a subject of your code and coding practice.
I would not call this a factory, as I believe the responsibility, usage and behaviour of the creational class and of a factory as desribed in the factory design pattern are slightly different.
In your first example, you say that passing the $logger to the constructor is better than getting the instance from within the constructor. I agree that this is cleaner and more testable, but there are situations where this is equally bad. If you look at it from a performance perspective, then in your case, you always have to have a Logger instance to be able to use the class, even if under circumstances your class is not going to use it.
So in situations where the singleton object is a heavyweight (which is often the case with singletons), performing lazy instantiation (getting the instance when you need it instead of at constructor time) might be better.
If the class is not going to use it but needs the logger only under some circumstances I would pass the logger instance to the methods that require it. If this does not work I would think about hiding the heavyweight object in a proxy so that the proxy instantiates the heavyweight on request and forwards all calls to this instance then.
a singleton exists in the most cases by definition. so you can't save performance there.
if you don't need it, the often overlooked "null object" can be helpful.
Hello, you have a great blog here! I'm definitely going to bookmark you!
This looks stupid to me : class Foo {
protected $logger; public function __construct() { $this->logger = Logger::getInstance(); } ... } Why would you load a Logger like this on a class variable? Wy not use it in your function directly with a local far? This Looks just as stupid to me for the above reason and may be even more stupid. class Foo { protected $logger; public function __construct(Logger $logger) { $this->logger = $logger; } ... }
Depends on how many times you use the logger. Maybe the logger is not the best example here, you might replace it with $ANY_OTHER_DEPENDENCY. The point is not the logger itself, but that the latter example is better testable, maintainable and easier to understand regarding what Foo depends on.
![]() ![]() ![]() |
![]() ![]() Calendar![]() Archives![]() Categories![]() Quicksearch![]() Blogs we read...![]() Syndicate This Blog![]() Blog Administration![]() ![]() |




