Ok, what the hell is with all this talk about design patterns? The bookstore has books dedicated to the subject, experts in all the different computer language fields are talking about them, and how the hell does it make my programming life easier? The answers may be “They are gossips”, “Authors have nothing else to write about”, and “Yes they will make things a bit easier for you in the way of programming”. So lets start with a simple one on this entry of the Programmer’s Underground!
If you have ever gone to chapters or barnes and noble bookstores you may have seen books on “Design patterns” for any given language or a book on it completely on its own. You might have even picked it up and saw some kind of complex discussion on how these patterns will revolutionize the way programming is done in large scale projects or how it can do everything including get your kids ready for school, make their lunch, and even drive them there while you sleep in. I will be the first to tell you that they are not fabulous wonderous super kick ass code modules that will save the world. They are however very cool and can save you a bit of time, code redundancy, and having to decipher that mess of complexity which is project code.
We will discuss one of the more simplistic of all the patterns and show you that they don’t have to be incredibly complex to understand and use. Once you got the idea under your belt you will be ready to go and most likely remember it for your next project. Then you can whip out witty comments to your co-workers like “You know, we could simplify this with a singleton pattern here and cut out all this garbage here, making it more elegant.” Then you know, you may go on to have that lavished quarter million dollar a year job where everyone in the software world will idolize you. That or your boss will give you a pat on the back, take all the credit, and you can get your standard paycheck knowing you did some good in the world. We can dream can’t we?
Here is the main idea behind the singleton pattern. When we have something we want to create once and share (like a database connection object for instance), we should create an instance of it if it doesn’t exist, otherwise return a reference to the object already in existence. Why create another copy of the exact same object and use more resources? I shall show you in an example. Below is a class called db. It controls access and establishes a connection to our database. Whenever we want to create a database connection it will either create it if it doesn’t exist or give us the reference to the one connection in existence already.
PHP 5 Example
class db { // Static variable (available without needing an actual instance) private static $db_instance = null; private function __construct() { // Restrict the constructor, we don't want programmers to use it. } protected function __clone() { // We don't want them to clone either } // getInstance either creates an instance or returns our static variable version if it already exists. static public function getInstance() { if(is_null(self::$db_instance)) { // Create database connection here $link = mysql_connect("localhost", "admin", "adminpass") or die(mysql_error()); mysql_select_db("test_database",$link) or die(mysql_error()); // Set our static variable to the link identifier. Now it is available in our static variable. self::$db_instance = $link; } return self::$db_instance; } }
So the code above is pretty straight forward. I will show you this in action in just a moment. What we have done here is closed off the constructor and the clone implementations so that programmers will be forced to use our getInstance() method to create their object. The idea behind this method is that we test to see if we already have a link to our database, if not we create it and store it, otherwise we return the copy of the connection that is already made. Rather than having to create a database connection object each time and connect it, we can share one connection across the page, each time using getInstance() to either create the connection or give us the pointer to the current connection.
Here is an example of how we use it…
// fetch database connection (creates it if it wasn't created before) $db_con = db::getInstance(); class DB_GetMember_Info { private $db = null; private $infoarray = array(); public function __construct() { // Set our private member to existing connection $this->db = db::getInstance(); // Now we use it to run our queries and pull up some members to store in our private array $result = mysql_query("select name, address, phone from members",$this->db); while ($member = mysql_fetch_object($result)) { array_push($infoarray,$member); } } ... }
Notice how we access the getInstance() static method through the class name? We don’t create the object, we simply access the static method using the name db. This is the same way you would access sqrt() through using the class name math in a language like C++ or Java.
Now the brilliant thing behind this is that we could create several copies of the DB_GetMember_Info class and one each one is created it is using the same connection link rather than creating and closing their own copies during creation.
The whole idea behind this pattern is saving resources by sharing something like a connection or maybe a whole “settings” object which sets and gets user settings. You would have one copy of the settings class created at any one time and multiple classes could use it without needing to create copies of the settings object. The one trick to remember about this pattern is that it uses a static variable. It must be static so that we can use the variable without needing to create instances of the object. This trick is also its primary drawback… it suffers from the same problem that global variables do because it is public and static very much a global environment. Thus it can be corruptible if you are not careful.
You will see this pattern in combination with other patterns since the pattern it provides is great for reducing redundant code and complexity, making other patterns easier as well. I hope this little glimpse into the singleton pattern will spur some new ideas of how you can go about developing better code and reducing the amount of work you have to do. Something like the connection idea above would be great for games or anything that may become connection intensive, constantly opening and closing the same connection.
Now go forth and speak the word of singleton to your co-workers, be leet, and show your boss that you kick ass!
B)