Die Factory Klasse
Oft kommt es vor, dass man von einer Klasse in der ganzen Anwendung genau eine Instanz benötigt, oder dass diese Instanz vielleicht sogar abhängig von bestimmten Umgebungsparametern aus unterschiedlichen Klassen erzeugt werden soll.
Ein Beispiel dazu ist die Instanz für die Datenbankverbindung. Sie sollte es nur ein einziges Mal in der Anwendung geben und könnte in Abhängigkeit vom konfigurierten Datenbanksystem aus verschiedenen Klassen erzeugt werden müssen.
Ein weiteres Beispiel ist eine Klasse welche die Konfiguration für die Anwendung enthält. Sollten hier in der Anwendung verschiedenen Instanzen verwendet werden, so könnten dann auch mehrere Konfigurationsvarianten für die Anwendung vorhanden sein. Da die Konfiguration auch irgend wann mal gesichert werden müssen, könnten sich die verschiedenen Instanzen überschreiben. Es muss also sichergestellt werden, dass es nur eine einzige Instanz dieser Klasse in der Anwendung gibt.
Die Lösung heißt Factory Klasse. In einer Fabrik wird ja was hergestellt. In unserem Fall sind das die Instanzen von bestimmten Klassen unter bestimmten Bedingungen. Hier das Codebeispiel:
class Factory {
static private $DB; //Hält das aktuelle Datenbankobjekt.
static private $Conf; //Hält die aktuelle Konfiguration.
//Durch das & wird eine Referenz auf die $DB-Instanz zurückgegeben.
//Damit ist sichergestellt, dass es das DB-Objekt nur einmal gibt.
static public function &getDBO() {
//Sollte die Datenbank noch nicht initialisiert worden
//sein, so muss erst die Funktion createDBO() aufgerufen werden.
if (!is_object(Factory::$DB)) {
Factory::createDBO();
}
return Factory::$DB;
}
static private function createDBO() {
//Sollte noch keine Konfiguration vorhanden sein, diese laden.
if (!is_object(Factory::$Conf)) {
Factory::$Conf=Factory::createConfig();
}
//Jetzt DB-Objekt erzeugen.
if (Factory::$Conf->DBType == "Mysql") {
//Hier Code zur Erzeugung der MySQL-Instanz
Factory::$DB=new DBmysql;
}
else if (Factory::$Conf->DBType == "MSSQL") {
//Hier Code zur Erzeugung der MSSQL-Instanz
Factory::$DB=new DBmssql;
}
else{
die("Datenbanktyp ".Factory::$Conf->DBType." unbekannt. Anwendung wird angehalten");
}
}
static public function &getConfig() {//Durch das & wird eine Referenz auf die $Config-Instanz zurückgegeben.
//Sollte die Configuration noch nicht initialisiert worden
//sein, so muss erst die Funktion createConfig() aufgerufen werden.
if (!is_object(Factory::$Conf)) {
Factory::createConfig();
}
return Factory::$Conf;
}
static private function createConfig() {
//Config Objekt erstellen.
Factory::$Conf=new Config();
}
}
?>
Wenn nun irgendwo in der Anwendung ein DB-Objekt benötigt wird, so kann es mit $DB=Factory::getDBO(); beliebig oft geholt werden. Es handelt sich dabei immer um die gleiche Instanz. Genau so kann mit der Konfiguration verfahren werden. $Conf=Factory::getConfig(); Wird am Ende der Anwendung die Speicherung der Konfiguration aufgerufen (z.B. in Destruktor), so gibt es keine Überschneidung, da es ja immer die gleiche Instanz ist. Voraussetzung ist natürlich, dass die Instanzen ausschließlich über die Factory Klasse geholt werden.
Fazit: Eine Factory Klasse findet immer dann Verwendung, wenn eine Instanz nur ein mal in der Anwendung vorkommen soll, oder in Abhängigkeit von Parametern aus verschiedenen Klassen erzeugt werden muss.
Aktualisiert (Montag, den 31. Oktober 2011 um 09:16 Uhr)