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.