Date: 5 June, 2007 - 05:55
Last week when I started writing about Design Patterns, I mentioned the Singleton Pattner offhand with the assumption that everyone was familiar with it. Unfortunately, I was off in my assumption...
The Singleton Pattern is probably one of the first and definitely one of most common Design Patterns that you'll find. A quick and dirty definition from Wikipedia says:
the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.
Which means what exactly? To think of it in simple terms, a Singleton is a way of working with any limited resource, especially those which are used frequently in many different areas... but the key aspect is that there is exacly one and only one instance. It's similar to having the television remote. There's only one remote and you may or may not have ultimate and exclusive control while you hold it.
Alright, so what would you use a Singleton for? Let's say you have a database. You could create a new database connection each and every time you need to make query but each time you'll have to deal with setting up the connection. In addition, if you forget to close the connection, you could run out of connections and crash your application. Luckily, the Singleton comes to save the day. Instead of creating your own each and every time, you simply request a connecton from your DatabaseManager and it handles the rest. You don't need to know or worry about anything else... the Singleton handles the setup, tear down, management, etc. Here is a simple implementation in PHP:
<?php
class Singleton {
// object instance
private static $instance;
private function __construct() {
// database connection code goes here
// notice that this method is private to prevent someone
// from creating their own instance, all access must
// come through getInstance() below
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new Singleton();
}
return self::$instance;
}
}
?>Unfortunately, Singletons can be abused. Although it works, they shouldn't be used for "global variable buckets". You can use normal globals and involving a Singleton just adds unncessary code.
When in doubt, remember that a Singleton coordinates/limits the behavior of the system. If you find yourself calling your Singletons to get system parameters, you've either a) over complicated the configuration or b) have badly designed Singletons.










thread safety
Hi Keith,
Just a quick comment about your singleton code; there's a potential thread safety issue. In your code:
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new Singleton();
}
return self::$instance;
}
It's possible that thread calls :
if (self::$instance === null)
then gets interrupted and thread 2 calls the same code and passes. Then they both execute:
self::$instance = new Singleton();
This could be a big issue depending on what your singleton is constructing...
I would rather recommend that you do:
private static $instance = new Singleton();
This way it's done before any of the methods can be called, and only once as the static instance is created.
Just my little tip from having been tripped up by the singleton.
Regards,
Steph
Good Catch
Thanks for the comment and your point is taken.
Using the initial implementation, it's possible for numerous concurrent instances to be created which defeats the whole purpose. Your tweak would pre-instantiate the Singleton and simply return the one that's there in all cases.