note 52003 deleted from language.oop5.patterns by danbrown

From: Date: Sun, 23 Jan 2011 16:48:32 +0000
Subject: note 52003 deleted from language.oop5.patterns by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-176124@lists.php.net to get a copy of this message
Note Submitter: richard dot quadling at bandvulc dot co dot uk ---- In response to Scott Mattocks response to Jimmy Paterson ... You cannot mix singletons and subclasses securely. Why? The standard way of creating a singleton is with the method ... // Hold an instance of the class private static $instance; // The singleton method public static function singleton() { if (!isset(self::$instance)) { $c = __CLASS__; self::$instance = new $c; } return self::$instance; } This returns either the previously created instance or a new instance of this class. As the constructor is private (which inhibits the manual creation of the class), you cannot alter the value of $c in the example above by passing it to the function, as suggested by Scott Mattocks. Why? __construct() is private!!!! self::$instance = new $c; where $c is NOT Singleton will result in a fatal error ... Fatal error: Call to private Singleton::__construct(). You have to have __construct() as private, otherwise you can create multiple instances of the singleton, explicit contra the reason for the pattern to start with. Now. Say you do make the __construct() protected (can only be called from this class or subclasses), then you MAY have a little more success. But not much ... <?php class Singleton { // Hold an instance of the class private static $instance; // A private constructor; prevents direct creation of object protected function __construct() { echo 'I am constructed'; } // The singleton method public static function singleton($classname = __CLASS__) { if (!isset(self::$instance)) { self::$instance = new $classname; } return self::$instance; } } class SubClass extends Singleton { public static function singleton() { return parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance. } public function TellMe() { echo 'You are in here.'; } } $subclassInstance = SubClass::singleton(); $subclassInstance->TellMe(); ?> gives you ... I am constructedYou are in here. But you are not going to be able to extend this to more than 1 subclass as the singleton exists for the base class ... <?php class Singleton { // Hold an instance of the class private static $instance; // A private constructor; prevents direct creation of object protected function __construct() { echo 'I am constructed'; } // The singleton method public static function singleton($classname = __CLASS__) { if (!isset(self::$instance)) { self::$instance = new $classname; } return self::$instance; } } class SubClass extends Singleton { public static function singleton() { return parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance. } public function TellMe() { echo 'You are in here.'; } } class SubClass2 extends Singleton { public static function singleton() { return parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance. } public function TellMeMore() { echo 'You are over here.'; } } $subclassInstance = SubClass::singleton(); $subclassInstance->TellMe(); $subclass2Instance = SubClass2::singleton(); $subclass2Instance->TellMe(); ?> results in ... I am constructedYou are in here.You are in here. and NOT I am constructedYou are in here.You are over here. as you might have thought. Basically, subclassing and singletons don't really mix.

« previous php.notes (#176124) next »