Parantatatam
mag Cookies & Kekse
Hallo ihr beiden,
ich habe mich jetzt ebenfalls mit diesem Thema näher auseinander gesetzt und eine eigene Variante geschrieben, welche eines der beiden Probleme von Zodiac löst: die argumentlosen Methoden und die klassenübergreifende Variablendeklaration.
ExtensionStorage
Registry
Extensionable
Und damit das Ganze auch noch hübsch zu erweitern ist:
Im Gegensatz zu der Variant Zodiacs erben alle angesprochenen Klassen von der Klasse Extensionable.
Weiterhin bleibt das Problem, dass man dem Konstruktor keine spezielle Funktionalität zuweisen kann. Man könnte dies allerdings über ein Callback zu einem Alias-Konstruktor (beispielsweise "initialize") lösen, welchem man die Argumente des Konstruktors übergibt.
ich habe mich jetzt ebenfalls mit diesem Thema näher auseinander gesetzt und eine eigene Variante geschrieben, welche eines der beiden Probleme von Zodiac löst: die argumentlosen Methoden und die klassenübergreifende Variablendeklaration.
ExtensionStorage
PHP:
<?php
class ExtensionStorage {
private static $extensions = array();
public static function get($extensionable) {
if(isset(self::$extensions[$extensionable]))
return self::$extensions[$extensionable];
return false;
}
public static function has($extensionable) {
return isset(self::$extensions[$extensionable]);
}
public static function extend($extensionable, $extension) {
self::$extensions[$extensionable][$extension] = $extension;
}
}
?>
PHP:
<?php
class Registry {}
?>
PHP:
<?php
class Extensionable {
private $__methods = array();
private $__variables = null;
public function __construct($variables = null) {
if($variables instanceof Registry)
$this->__variables = $variables;
else
$this->__variables = new Registry;
$this->__get_parent(get_called_class());
}
private function __get_parent($parent) {
if($extensions = ExtensionStorage::get($parent)) {
foreach($extensions as $extension) {
if(ExtensionStorage::has($extension)) {
$this->__get_parent($extension);
}
else {
if(($methods = get_class_methods($extension)) !== null && $methods !== array()) {
$instance = new $extension($this->__variables);
foreach($methods as $method) {
if($method[0] . $method[1] === '__')
continue;
if(isset($this->__methods[$method]))
throw new Exception('Cannot redeclare method "' . $method . '"');
else
$this->__methods[$method] = $instance;
}
}
}
}
}
}
public function __call($method, $parameters) {
if(isset($this->__methods[$method]))
return call_user_func_array(array($this->__methods[$method], $method), $parameters);
}
public function __get($name) {
if(isset($this->__variables->{$name}))
return $this->__variables->{$name};
return null;
}
public function __set($name, $value) {
$this->__variables->{$name} = $value;
}
}
?>
Und damit das Ganze auch noch hübsch zu erweitern ist:
PHP:
<?php
function extend($extensionable, $extension) {
ExtensionStorage::extend($extensionable, $extension);
}
?>
PHP:
<?php
class A extends Extensionable {}
class B extends Extensionable {}
class C extends Extensionable {}
extend('A', 'B'); # erweitert A um B
extend('A', 'C'); # erweitert A um C
?>
Zuletzt bearbeitet: