Wenn man die drei Design Patterns aus den vorangegegangen Artikeln kombiniert, bekommt man sowas wie ein "Vererbtes Singleton-Factory-Registry". Dieses "Pattern" setze ich momentan erfolgreich als Basis des Refactoring/Redesigns meines kleinen Frameworks openWebX2 ein.
Als Basis dient hier eine erweiterte Version unserer abstrakten Singleton-Klasse:
-
<?php -
abstract class SingletonFactoryRegistry {
-
-
// Instanzen werden in einem statischen Array gespeichert -> Registry -
private static $instances = array();
-
-
// Wie immer die Singleton-Vorraussetzungen: -
protected function __construct() {}
-
final private function __clone() {}
-
-
// Die um Parameter erweiterte Singleton-Instanz -
final static public function getInstance($mixedParams = NULL) {
-
static $instances = NULL;
-
$myHash = md5(serialize($mixedParams));
-
return $instances[$myHash] ?: $instances[$myHash] = new static($mixedParams);
-
} -
-
// Der "Loader", welcher sicherstellt, dass Objekte korrekt -
// instanziiert werden, entweder via Singleton oder via Konstruktor. -
// Diese Instanzen werden dann gespeichert. -
// Also eine Art Factory-Registry -
final static public function load($strObject, $mixedParams = NULL) {
-
$strObjectHash = md5($strObject.serialize($mixedParams));
-
if (!isset(self::$instances[$strObjectHash])) {
-
// Wenn das Objekt den Singleton benutzt, dann wird es via getInstance -
// instanziiert, ansonsten via Konstruktor. -
self::$instances[$strObjectHash] = (method_exists($strObject, 'getInstance')
-
? $strObject::getInstance($mixedParams)
-
: new $strObject($mixedParams));
-
} -
return self::$instances[$strObjectHash];
-
} -
} -
?>
Dieses Object können wir nun benutzen um beliebige Objekte zu "laden". Wir legen uns dazu erst mal 2 unterschiedliche Klassen an:
-
<?php -
-
// Object benutzt das Singleton-Pattern -
class mySingleton extends SingletonFactoryRegistry {
-
-
private $__id = NULL;
-
-
// Der Constructor kann einen Parameter bekommen -
protected function __construct($strID = NULL) {
-
$this->__id = $strID;
-
} -
} -
-
// Dieses Object hat einen normalen Konstruktor -
class myStandard {
-
-
private $__id = NULL;
-
-
public function __construct($strID = NULL) {
-
$this->__id = $strID;
-
} -
} -
?>
Wir können nun beide Arten von Objekten über die load Methode unserer "SingletonFactoryRegistry"-Klasse instanziieren:
-
<?php -
$myObj1 = SingletonFactoryRegistry::load('mySingleton');
-
$myObj2 = SingletonFactoryRegistry::load('myStandard');
-
-
// Parameter: -
$myObj3 = SingletonFactoryRegistry::load('mySingleton','1');
-
$myObj4 = SingletonFactoryRegistry::load('myStandard','2');
-
-
// Nun testen wir ob das SingletonFactoryRegistry-Pattern funktioniert: -
-
$myObj5 = SingletonFactoryRegistry::load('mySingleton','1');
-
$myObj6 = SingletonFactoryRegistry::load('myStandard','2');
-
-
var_dump($myObj1);
-
var_dump($myObj2);
-
var_dump($myObj3);
-
var_dump($myObj4);
-
var_dump($myObj5);
-
var_dump($myObj6);
-
?>
Wie erwartet, sehen wir, dass $myObj3 und $myObj5 ebenso auf das identische Objekt verweisen wie $myObj4 und $myObj6:
-
object(mySingleton)#1 (1) { ["__id":"mySingleton":private]=> NULL }
-
object(myStandard)#2 (1) { ["__id":"myStandard":private]=> NULL }
-
object(mySingleton)#3 (1) { ["__id":"mySingleton":private]=> string(1) "1" }
-
object(myStandard)#4 (1) { ["__id":"myStandard":private]=> string(1) "2" }
-
object(mySingleton)#3 (1) { ["__id":"mySingleton":private]=> string(1) "1" }
-
object(myStandard)#4 (1) { ["__id":"myStandard":private]=> string(1) "2" }
Wir haben uns somite eine Art Object-Cache gebaut, der momentan noch innerhalb eines Prozesses seine Grenzen findet. Interessant wäre aber die Möglichkeit, die Objekte persistent zu speichern. Dieses nehmen wir in den nächsten Folgen unserer kleinen Serie in Angriff ;-)
Jens
Willkommen zum zweiten Teil meiner kleinen HowTo-Serie. Heute werde ich Euch zeigen, wie man einem Android-Handy zu einem Zugang zum OpenVPN-Server aus dem 



