Posted by: phillipnb | September 29, 2010

Analysing Singleton Pattern in PHP


As a PHP developer you must have heard of the term ‘design patterns’. You must have heard your collegues or boss or your friends talking about ‘x’ design pattern or ‘y’ design pattern. Well, the most ideal definition for the word ‘design pattern’ is that design patterns are elegant and efficient solutions for commonly occuring problems in software development. Design Patterns were not discovered suddenly but a ceratin set of informal techniques were developed when developers encountered a particular type of problem and used these informal techniques to solve those problems. As time went by these techniques were polished rectifying many flaws in it by trial and error so that an established design pattern was allowed to evolve. In general, patterns are not associated with any particular programming language. In fact, patterns can be compared to ‘blueprints’ that can be implemented in any programming language. If you look on the web or any textbooks or if you have listened to many design pattern gurus, you can hear several other definitions for design patterns all of which are correct and more or less harp on the same idea. For example:

  • Some people say that design patterns are a form of generalised templates or well established methods which will tell you on how to solve a problem
  • Some others say that design patterns will tell what solutions to use for a particular problem
  • Some others will say that design patterns are the sum of all best practices and optimised reusable solutions which were followed for many years for solving a particular problem

What ever your understanding or defintion of design pattern is, every defintion ends in the same and single idea that design patterns are ‘generalised’ solutions for recurring problems in software development. There is no single or universal design pattern for all problems. A design pattern should not be confused as a specific class or finished code, it is just a framework, kind of a skeleton of a human body.

One question that will pop up in your mind after reading the above paragraph will be ‘Are design patterns found only in software development’. The answer is a big ‘NO’. Design patterns deals with ‘problems’ and problems can be found in all branches of study and almost everywhere. I am not an expert to tell if design patterns are documented and used repeatedly in other fields of study (like physics,arts,philosophy etc) as in software development. In fact, design patterns were introduced by Christopher Alexander, a civil engineer,who found that soluton to a particular problem became better and better when it was refined after each use.

Advantages of using Design Patterns:

  • Design patterns helps object oriented programming become more rigid so that the flexibility of the latter is not misused
  • As you are creating kind of a skeleton/framework using design pattern, it leads to better and cleaner code
  • Design Patterns forces developers to follow structured programming practices. This in turn improves code readability
  • Design Patterns helps the development team to speed up the coding because the solution to your problem is already given by the Design Pattern
  • The biggest advantage is that design patterns solve a problem using an established solution. This helps better comminication and co-ordination within the development team as we already have a framework visible to everybody

Patterns belonging to software development in general can be divided into two, one is called design patterns and the other is called architectural patterns. While design patterns can be considered to operate at a lower level defining relationships between classes and objects, architectural patterns operate at higher levels defining the entire application system. Design Patterns can again be subdivided into structural, creational and behavioral patterns, more about them maybe in another write-up. In this article we will be talking about a design pattern called ‘Singleton Pattern’.

The definition of singleton pattern is that a class implementing singleton pattern has only a single object or a single instance at all times. Singleton pattern has some conditions or behavior associated with it like:

  • It is good to hold the instance of a singleton class in a static member variable so that you can access them without instantiating the class. You can also use a static method as the single entry point into this class
  • To prevent instantiation from outside the singleton class, you can make the class constructor as private or protected
  • You can prevent this class from being cloned
    (use private function __clone() {})

There are plenty of uses of singleton design pattern. One argument that goes in favor of singleton pattern is that singleton design pattern restricts the instantiation of a class to a single object and hence there is less or zero memory wastage as the same class is not instantiated multiple times. Hence only one instance of the instantiated class is allowed to exist globally which will provide kind of a single entry point for that particular class. Another argument which is in favor of singleton class goes like this – In PHP, variables have scope restriction. A variable that is visible outside a function will not be visible inside the function and vice-versa. To overcome this you can use superglobals. But, too many super globals will be confusing to any developer. Another alternative is to pass the required variable to the function so that it is available inside that function. This solution is not practical when the number of parameters passed become more than a dozen. Here is where the beauty of singleton pattern comes into picture because it provides global availability of a single object which cannot be modified.

Enough of this melodious music about singleton pattern, let us now discuss an example to actually understand what this is all about. There are several examples that demonstrates the use of singleton pattern but the one that I like the most is the use of singleton pattern with databases. In general, when we access the database we establish a connection to the database. Infact, we create a new connection when we do a ‘select’, again we create a new connection if we do another ‘select or update’ and so on.If we keep on doing this, we are going to degrade the performance of the application that we are working on as well reduce the bandwidth of the network because of frequent database calls. It is here that singleton provides a cleaner solution. When we use singleton pattern here, we are creating only one instance of the connection and then will reuse that connection again and again. By using singleton pattern we also have another advantage – we are not going to initiate a connection until one of our methods actually request it. Some may argue that we can use a global variable to store the instantiated connection and use it anywhere in the code. Yes, you can do that but we already discussed the drawbacks of globals in previous paragraphs. Also, if we use global, then we need to intialize the connection a bit earlier in the code. Hence, in general when you want to communicate with the database, you would like have only a single connection as multiple connections are a waste of resources. Here is an example which proves what I am talking about:

class singletonDatabase

{

    private static $myDbInstance = NULL;

    private function __construct()

    {

    }

    public static function getNewInstance()

    {

       if (!self::$myDbInstance)

       {

         self::$myDbInstance = new
         PDO ('mysql:host=localhost;dbname=School',
          'myusername', 'mypassword');

       }

       return self::$myDbInstance;

    }

    private function __clone()

    {

    }

}

Suppose you have a table called ‘Student’ and you want to display the fields using the above class, you can access the database by:


    $myQuery = "SELECT StudentID,StudentName FROM Students";

    $result = singletonDatabase::getNewInstance()->query($myQuery);

    foreach($result as $row)

    {

        print $row['StudentID'] .' - '. $row['StudentName'] ;

    }

So, whenever we access the database, if you look into the class singletonDatabase, you can see that it checks to see if an instance of the connection is already present. If it is present it returns the same connection, if not (only for the first time), it creates a new connection. This singleton design patterns ensures that at any given moment, there will just be one instance of the database connection. The above class cannot be instantiated from outside the class as the constructor is ‘private’ and the instance of the class cannot be cloned by making the magic function __clone() as ‘private’.

Conclusion – As soon as you start working on a project, one should not blindly make the decision of using a design pattern. Start small, try to build the skeleton and as you progress if the work that you are doing shapes up or resembles an x-pattern or a y-pattern, then think of whether it will be useful to rewrite that part of the code using a design pattern. Whether you should use singleton pattern or a global variable depends on your application and circumstances. No generalised solution can be suggested in such cases. Honestly, design patterns are useful only in large applications where there are large number of lines of code. Implementing a design pattern for a few lines of code is like trying to use your car to move two pencils from the living room to the bed room of your house.

I hope I was able to explain to you very briefly about Singleton Design Patterns, Till Next Time…Keep programming using PHP

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: