Friday, August 05, 2011

Singleton design pattern with simple examples


Singleton design pattern is a very common design pattern ,which makes it impossible to have more than one instance of a class.


For example

$obj1=new TestClass();
$obj2=new TestClass();

here we can see we have created two instance and object of TestClass and we can create more.

But If we want to restrict to create only instance of class. not more than one. then how we can do. it is singleton design pattern. by this design pattern . we can a class that have only one instance.
In short,  Singleton pattern ,which makes it impossible to have more than one instance of a class.

class Database
{
private static $_instance;

private function __construct() { }

public static function getInstance()
{

 if (!isset(self::$_instance)) {
   $c = __CLASS__;
   self::$_instance = new $c;
 return self::$_instance;
 }
return NULL;
}

private function __clone() {}
}

$db = Database::getInstance();
Look we have make constructor private. thats the main feature of singleton pattern.
for example we can't create object like this
$db=new Database();
we can't do this. because constructor is private.
getInstance() method is static. 
$db = Database::getInstance();
if we var_dump($db);
suppose we want create another instance

$db2=Database::getInstance();

var_dump($db2);

try this. copy paste this code and see whats result

class Database
{
private static $_instance;

private function __construct() { }

public static function getInstance()
{

 if (!isset(self::$_instance)) {
   $c = __CLASS__;
   self::$_instance = new $c;
 return self::$_instance;
 }
return NULL;
}

private function __clone() {}
}

$db1 = Database::getInstance();
$db2 = Database::getInstance();
var_dump($db1);

var_dump($db2);

output should be like this
object(Database)#1 (0) { } NULL

it means $db2 is null. we cannot craete instance twice.
one important thing i should mention here. why we make __clone(magic methof) private. Because to prevent it from copying class

Please read about __clone function (i will explain them  in coming article)

for example

remove __clone function with class defination

then write this

$db1 = Database::getInstance();
$db2 = clone($db1);
var_dump($db1);

var_dump($db2);

this time $db2 is not null.

so if we make __clone() private. we cannot able to access it and then we cannot create instance by clone method

Be sure we made constructor private and clone too.


Why we need singleton. because we want to create one instance of database.

I want to give example of daily life to make you understand.

For Example there are many football player like David Backam (England), Messi(Argentina) or Klose(Germany) and alot more

David Backam is only in whole world. i am not talking about name. may be there is another person with same name. but his shape his age and other factor will not be same.

Sohail Anwar and only in one world. Ajmal is only one. and so on.

so what i mean is there is only one David beckam in the world . We have class with name

class DavidBeckham
{
 //functions here


}

we want to create only one instance
$david=DavidBeckham::getInstance();

suppose there are some method for Beckham

$david->kickBall();
$david->playCorner();
$david->doGoal();

this is just example to show you daily example.


we cannot apply this like this. idea will be wrong

$david1=new DavidBeckham();
$david2=new DavidBeckham();

If you do like this. Idea is wrong in real life situation. because there is only David backham. there cannot be two david beckham in real life.
As i said earlier there are many football player. but david beckham is only one.


we can also do like. dont laugh. this is just an example :-D

$osama=OsamaBinLaden::getInstance();
$osama->killPeople();
$osama->doBombBlast();
$osama->KillAmerican();

:-D what i mean is there was only one osama bin laden. may be he now dead or not. ALLAH knows. but there was only one osama bin laden.


Another Good example . you have only one dsl connection. you dont want two dsl for one computer. there is only one lan port. and you want to connect with only one


you can't do like in real situation

$myNet1=new MyDsl();
$myNet2=new MyDsl();
$myNet1->connect();
$myNet2->connect();

Question. is it correct to connect two dsl to one computer. wrong idea. you just need one connection at one time to one computer

Yeah you can connect computer with wireless and well as cable dsl at same time. But you cannot connect two cable dsl at same time.

$myNet=MyDsl::getConnection();
$myNet->connect();

This is right implementation.

I think , you have understand concept of singleton pattern with these daily life example.


Please Copy paste this code to a file and see output


class Dsl
{
private static $_connection;

private function __construct() {

}
// If there is no instance, create one
public static function getConnection()
{

 if (!isset(self::$_connection)) {
   self::$_connection = new Dsl();
     return self::$_connection;
 }
return NULL;
}
public function connect()
{
echo " Net is connected";
}
public function disconnect()
{
echo " Net is disconnected";
}
// Block the clone method
private function __clone() {

}
}

$myNet1 = Dsl::getConnection();
$myNet1->connect();

$myNet2 = Dsl::getConnection();
$myNet2->connect();


You will notice it will print "Net is connected" only one. although we have created instances twice. but it connect dsl only once

Please run this example and try it.


Please try this and if you have any queries please do comment here..


0 comments:

Digg Facebook Technorati Delicious StumbleUpon Reddit BlinkList Furl Mixx Google Bookmark Yahoo Add to Technorati Favorites TwitThis

Post a Comment