#1 13. Mai 2009 Singleton, Factory Method, extends? Hi Leute, ich bin am verzweifeln, keine Ahnung ob ich gerade ne Denkblockarde habe oder sonstwas ... Es geht um Folgendes: Ich habe einige Klassen die ich in jedem Modul brauche. Datenbank, Template, User ... Nun habe ich diverse Module die ich includiere ... jedes Modul hat nochmals eine eigene Klasse mit diversen Funktionen. Für diese Funktionen werden die Objekte der Klassen die ich quasi immer brauche (Datenbank, Template, User) benötigt. Wie kann ich diese Klassen bzw. die Instanzen miteinander verknüpfen? Ich lese immer was von Singeltons und Factory Method, habe es aber leider immer noch net gerafft. Ich würde mich über nen kleines "Tutorial" freuen, wie ich genau vorgehen muss, was ich beachten muss, damit ich endlich von überall auf meine Daten zugreifen kann ... Danke Leute!!! + Multi-Zitat Zitieren
#2 14. Mai 2009 AW: Singleton, Factory Method, extends? es gibts da eine möglichkeit mit der du alle globalen module in eine klasse lädst, der nachteil dabei ist nur, dass alle klassen die du da verwendest unterschiedliche methoden-namen haben müssen: PHP: <? php class Delegate { private $_instances = array(); public function addObject ( $oElement ) { // add one element on the end of the stack $this -> _instances [] = $oElement ; } public function __call ( $strMethod , $arrParams ) { // for each element in instance foreach( $this -> _instances as & $oElement ) { // get the class of the element $strClass = get_class ( $oElement ); // get all methods of the class $arrMethods = get_class_methods ( $strClass ); // case the method exists into this class if( in_array ( $strMethod , $arrMethods ) ) { // prepare caller $arrCaller = Array( $strClass , $strMethod ); // return the result of the method into the object return call_user_func_array ( $arrCaller , $arrParams ); } } // any object has the method // throw a exception throw new Exception ( " Method { $strMethod } not exist in this class " . get_class ( $this )); } } $s = new Delegate ; $s -> addObject (new Database ()); $s -> addObject (new Template ()); $s -> methodFromDatabase (); $s -> methodFromTemplate (); ?> eine bessere methode wäre wohl folgende: PHP: <? php class Database { private static $_instances = array(); public static function addObject ( $alias , $obj = null ) { if( is_object ( $alias )) { $obj = $alias ; $alias = get_class ( $obj ); } self :: $_instances [ strtolower ( $alias )] = $obj ; } public static function getObject ( $name ) { if(isset( self :: $_instances [( $name = strtolower ( $name ))])) return self :: $_instances [ $name ]; return false ; } } Database :: addObject (new Template ()); Dabatase :: getObject ( 'Template' )-> machWas (); ?> damit kannst du auch klassen "überschreiben" PHP: <? php Database :: addObject (new Template ()); Dabatase :: getObject ( 'Template' )-> machWas (); class SuperTemplate { public function __construct ( Template $tpl ) { $this -> tpl = $tpl ; } public function machWas () { /// code } } Database :: addObject ( 'Template' , new SuperTemplate ( Database :: getObject ( 'Template' ))); Database :: getObject ( 'Template' )-> machWas (); ?> + Multi-Zitat Zitieren
#3 19. Mai 2009 AW: Singleton, Factory Method, extends? Hm... wenn es "nur" darum geht, systemweit möglichst flexibel auf deine (während der Laufzeit erstellten) Objekte zugreifen zu können, dann würde ich an deiner Stelle mal das Registry-Pattern beäugeln . Du könntest eine Registry-Klasse mit einer statischen get- und set-Methode erstellen. Beispiel (ungetestet) (Registry.php): PHP: <? php class Registry { private static $_instances = array(); public static function set ( string $key , $mixed ) { self :: $_instances [ $key ] = $mixed ; } public static function get ( string $key ) { if(! self :: isRegistered () ) { throw new Exception ( "Key ' $key ' is not registered" ); } return self :: $_instances [ $key ]; } public static function isRegistered ( string $key ) { return array_key_exists ( $key , self :: $_instances ); }} ?> Benutzung: PHP: <? php require_once 'Registry.php' ; // deine systemweit gebrauchten Objekte $database = new Database (); $template = new Template (); Registry :: set ( 'database' , $database ); Registry :: set ( 'template' , $template ); // .................. irgendwo anders ;) Registry :: get ( 'database' ) -> query (); Registry :: get ( 'template' ) -> render (); ?> Du hast halt damit eine sehr flexible Lösung, mit der du deine Objekte "global" zur Verfügung stellst. Durch das Werfen der Exception kannst du sicherstellen, dass ein Objekt auch an dem Punkt vorhanden ist, an dem du es brauchst. Vllt. greifst du dir einfach die Zend_Registry-Klasse aus dem Zend Framework . Das wäre wohl eine einfache Lösung. MfG Chronos [EDIT] Pah! Da waren meine Finger wieder schneller, als meine Augen . Das 2te Beispiel von Murdoc arbeitet quasi nach dem gleichen Prinzip. Nur, dass du dich nicht verwirren lässt . + Multi-Zitat Zitieren