This morning, I was wondering about how to extend a singleton class such
that you could retrieve the new class when retrieving the singleton later.
In particular, Zend_Controller_Front is a singleton, but what if I want to
extend it later? A number of plugins in the Zend Framework, particularly
view helpers and routing functionality, make use of the singleton; would I
need to alter all of these later so I could make use of the new subclass?
For instance, try the following code:
class My_Controller_Front extends Zend_Controller_Front
{}
$front = My_Controller_Front::getInstance();
You'll get an instance of Zend_Controller_Front. But if you do the
following:
class My_Controller_Front extends Zend_Controller_Front
{ protected
static $_instance;
public
static function getInstance
() { if (null === self::
$_instance) { self::
$_instance =
new self
();
} return self::
$_instance;
}}$front = My_Controller_Front::
getInstance();
You'll now get an instance of My_Controller_Front. However, since
$_instance is private in Zend_Controller_Front, calling
Zend_Controller_Front::getInstance() will still return a
Zend_Controller_Front instance -- not good.
However, if I redefine Zend_Controller_Front::$_instance as
protected, and have the following:
class My_Controller_Front extends Zend_Controller_Front
{ public
static function getInstance
() { if (null === self::
$_instance) { self::
$_instance =
new self
();
} return self::
$_instance;
}}$front = My_Controller_Front::
getInstance();
Then the any time I call getInstance() on either
My_Controller_Front or Zend_Controller_Front, I get a My_Controller_Front
instance!
So, the takeaway is: if you think a singleton object could ever benefit from
extension, define the static property holding the instance as protected, and
then, in any extending class, override the method retrieving the instance.