[PHP] Singleton, Factory Method, extends?

Dieses Thema im Forum "Webentwicklung" wurde erstellt von pleq, 13. Mai 2009 .

Schlagworte:
  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!!!
     
  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 ();
    ?>
     
  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 .
     
  4. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.