note 72009 deleted from language.oop5.patterns by danbrown
| From: | danbrown@php.net | Date: | Sun, 23 Jan 2011 16:42:37 +0000 |
| Subject: | note 72009 deleted from language.oop5.patterns by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-176113@lists.php.net to get a copy of this message | ||
Note Submitter: david at bagnara dot org
----
Thanks for the example below of an extendable Singleton. I have enhanced it a little so the derived
class does not need to implement any functions. The technique to get an instance is now
$x = Singleton::connect( "derived_class_name")
<?php
class Singleton
{
/*
How to use:
extend new class from singleton
To connect:
$x = Singleton::connect( "CLASSNAME" ) ;
*/
private static
$instanceMap = array();
//protected constructor to prevent outside instantiation
protected function __construct()
{
}
//deny cloning of singleton objects
public final function __clone()
{
trigger_error('It is impossible to clone singleton', E_USER_ERROR);
}
public function connect( // return a (reference to) a single instance of className
$className // name of a class derived from Singleton
)
{
// see if class already constructed
if(!isset(self::$instanceMap[$className]))
{
// if not then make one
$object = new $className;
//Make sure this object inherit from Singleton
if($object instanceof Singleton)
{
// save in static array
self::$instanceMap[$className] = $object;
}
else
{
throw SingletonException("Class '$className' do not inherit from
Singleton!");
}
}
// return reference to single instanace of className
return self::$instanceMap[$className];
}
}
?>
<?php
class A extends Singleton
{
protected $rndId;
protected function __construct()
{
$this->rndId = rand();
}
public function whatAmI()
{
echo 'I am a ' . get_class( $this ) . ' (' . $this->rndId .
')<br />';
}
}
class B extends A
{
}
$a = Singleton::connect( "A" );
$b = Singleton::connect( "B" );
$a->whatAmI();// should echo 'I am a A(some number)
$b->whatAmI();// should echo 'I am a B(some number)
unset( $a ) ;
$c = Singleton::connect( "A" );
$d = Singleton::connect( "B" );
$c->whatAmI();// should echo 'I am a A(same number as above)
$d->whatAmI();// should echo 'I am a B(same number as above)
$a = new A();// this should fail
$b = new B();// this should fail
?>