Voting

: eight plus zero?
(Example: nine)

The Note You're Voting On

mightye at gmail dot com
18 years ago
To: Bryan

In this model it is still workable if your singleton variable is actually an array. Consider:
<?php
abstract class Singleton {
protected final static
$instances = array();

protected
__construct(){}

protected function
getInstance() {
$class = get_real_class(); // imaginary function returning the final class name, not the class the code executes from
if (!isset(self::$instances[$class])) {
self::$instances[$class] = new $class();
}
return
self::$instances[$class];
}
}
class
A extends Singleton {
}
class
B extends Singleton {
}

$a = A::getInstance();
$b = B::getInstance();

echo
"\$a is a " . get_class($a) . "<br />";
echo
"\$b is a " . get_class($b) . "<br />";
?>
This would output:
$a is a A
$b is a B

The only alternative as described elsewhere is to make getInstance() protected abstract, accept the class name as an argument, and extend this call with a public final method for every sub-class which uses get_class() in its local object scope and passes it to the superclass.

Or else create a singleton factory like this:
<?php
final class SingletonFactory {
protected static
$instances = array();

protected
getInstance($class) {
if (!isset(
self::$instances[$class])) {
self::$instances[$class] = new $class();
}
return
self::$instances[$class];
}
}
?>
The downside to this of course to this latter model is that the class itself doesn't get to decide if it is a singleton, the calling code gets to decide this instead, and a class that really wants or *needs* to be a singleton has no way to enforce this, not even by making its constructor protected.

Basically these design patterns, and various other meta manipulations (things which operate on the nature of the object, not on the data the object holds) could benefit greatly from knowing exactly what the final type of this object is, and not having native access to this information obligates work-arounds.

<< Back to user notes page

To Top