Zitat:
Zitat von php.de Vielen Dank für die wirklich sehr interessanten Beiträge.
Mein PHP-Singleton-Pattern sieht nun folgendermaßen aus: PHP-Code: <?php class C { private static $instance; private function __construct() { } public static function get() { if (self::$instance === null) { $class = get_called_class(); self::$instance = new $class; } return self::$instance; } private function __clone() { } private function __wakeup() { } } ?> Eines würde mich noch interessieren: darf man eigentlich von einer Singleton-Klasse erben? |
Um hier nochmal genereller drauf einzugehen, es ist sogar in einigen Fällen sinnvoll Singletons zu vererben, z.b. wenn man gewährleisten will das...
... Kind-Klassen Singletons sind, spätere Kind-Klassen aber nicht irgendetwas anderes werden können:
PHP-Code:
class Singleton {
private static $_instances = array();
final public static function getInstance() {
return !isset(self::$_instances[ get_called_class() ])
? self::$_instances[ get_called_class() ] = new static
: self::$_instances[ get_called_class() ];
}
final protected function __clone() {}
protected function __construct () {
echo __CLASS__.'-Class representation of construct.'."\n";
}
}
class superSingleton extends Singleton {
protected function __construct () {
echo __CLASS__.'-Class representation of construct.'."\n";
}
}
Oder die interessantere Variante:
... abstrakte Singletons Grundlage für ein "Instanziier mich einmal, aber sonst keine Kinder von mir"-Singletons.
PHP-Code:
abstract class aloneSingleton {
private static $_instance;
final public static function getInstance() {
if ( !is_null( self::$_instance ) ) {
if ( get_class(self::$_instance) !== get_called_class() )
throw new LogicException(get_called_class().' is an subclass of '.__CLASS__
.', instances are restricted to one instance overall, '
.'you tried to access the wrong stage of inheritance, use '
.get_class(self::$_instance).' instead.');
else return self::$_instance;
}
else {
self::$_instance = new static;
}
return self::$_instance;
}
abstract protected function __construct();
}
class A extends aloneSingleton {
protected function __construct() { echo __CLASS__.' created.'; }
}
class B extends aloneSingleton {
protected function __construct() { echo __CLASS__.' created.'; }
}
class C extends A {
protected function __construct() { echo __CLASS__.' created.'; }
}
class D extends B {
protected function __construct() { echo __CLASS__.' created.'; }
}
PHP-Code:
a::getInstance(); // all be good
PHP-Code:
a::getInstance();
/* thousands of lines later */
d::getInstance(); // LogicException
Ein Parade-Beispiel dafür wäre ein Log-Interface das du als Singleton entwickelst, aber bei dem du nicht möchtest, das Beispielsweise Error-Reporting zum User tritt und in einem file geloggt wird ( gleichzeitig ), sondern nur in ein File geloggt wird oder die Fehler zum User übermittelt werden. Diese Form der Processing-Logik ermöglich ebendso anderen Entwicklern nicht unabsichtlich irgendwo logs anzustoßen, die sie später beispielsweise nicht mehr wiederfinden, weil sie nicht wussten das sie überhaupt aktiviert wurden.
Wie nikosch schon sagte, Pattern sind Vorlagen, keine Entgültigen Stempel wie Dinge aussehen müssen. Klar sollte man sich schon an das Konzept halten, aber Design Patterns werden dir nie sagen ob sie in ihrer Basis vererbbar sind oder nicht. ( Ich denke da würde das Gesamt-Konzept Vererbung auch hinsichtlich Design-Patterns ins wanken geraten )