Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Problem mit Singleton

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Problem mit Singleton

    Ich raff's nicht. Für meine Datenbank funktioniert der Singleton Pattern ganz gut.
    Jetzt wollte ich das für die Übersetzung auch umsetzen.

    PHP-Code:
    <?php

    /*** Zend path setup ***/
    require '../_init.php';
    require 
    "../includes/classes/Zend/Translate.php";

    class 
    Translator
    {
        private static 
    $Instance false;

        private function 
    __construct()
        {
                
    self::$Instance = new Zend_Translate('ini''./language/en_US.ini''en');

                
    //var_dump(self::$Instance);
        
    }

        public static function 
    GetInstance()
        {
            if (!
    self::$Instance)
            {
                
    self::$Instance = new Translator();
            }
            return 
    self::$Instance;
        }
    }

    $translate Translator::GetInstance();
    var_dump($translate);
    ?>
    Das erste var_dump im Code zeigt mir, dass self::$Instance eine korrekte Instanz von Zend_Translate ist.
    Der Output im zweiten var_dump() ist jedoch:
    PHP-Code:
    object(Translator)#5 (0) { } 
    Das müsste doch eigentlich funktionieren?


  • #2
    Warum? Du überschreibst doch in GetInstance() die Variablenzuweisung aus dem Constructor...

    Gruß Jens

    Kommentar


    • #3
      Eine Möglichkeit wäre, deine Translator-Klasse vom Zend Translator erben zu lassen, im deinem Konstruktor einfach den Parent-Konstruktor, also den vom Zend Translator aufzurufen.

      Kommentar


      • #4
        Vor allem kann ich weder bei der Datenbankanbindung, noch beim Translator einen Sinn im Singleton erkennen. Ich würd das Konzept also noch mal ein wenig auf die Streckbank schicken...

        Gruß Jens

        Kommentar


        • #5
          In der Datenbank ist der Singleton ja wohl sehr hilfreich, weil ich mir nie Gedanken darüber machen muss, ob eine Verbindung besteht und ich auch nie zwei Verbindungen brauche...
          Warum rätst du mir denn davon ab? Der Singleton ist für sowas doch gerade prädestiniert.

          Das mit der Vererbung funktioniert. Das hatte ich vorher schon.
          Um den Translator in verschiedenen Teilen meiner Anwendung dann benutzen zu können, hatte ich auf einen Registry-Pattern zurückgegriffen.
          Das hat eigentlich keinen Vorteil, so lange das Translator-Objekt nicht zur Laufzeit zerstört wird. Da kann ich genauso gut auch gleich auf die Instanz des Translators zugreifen.
          Deshalb habe ich den obigen Code geschrieben...

          In der GetInstance() Methode ist self::$Instance ebenfalls leer.
          Ich verstehe nicht warum.
          Liegt es vielleicht daran, dass Zend_Translate nur private Objekte enthält?

          object(Zend_Translate)#6 (1) {
          ["_adapter:private"]=>
          object(Zend_Translate_Adapter_Ini)#7 (4) {
          ["_data:private"]=>
          ...

          Kommentar


          • #6
            Noch mal: Du überschreibst Dir mit Deiner getInstance-Methode den Wert, den Du vorher im Construkter da rein geschrieben hast!

            Mit dieser Zeile hier:
            PHP-Code:
            self::$Instance = new Translator(); 
            passiert folgendes:
            1. Objekt vom Typ Translator wird erstellt
            2. Constructor wird aufgerufen
            3. Im Constructor schreibst Du per
              PHP-Code:
              self::$Instance = new Zend_Translate(/* ... */); 
              ein Objekt vom Typ Zend_Translate in self::$Instance.
            4. Das in 1) erstellte Objekt wird in die Variable self::$Instance gesteckt.


            Zum Thema "Wann verwende ich Singleton":

            Nur dann, wenn es kein theoretisch mögliches Szenario gibt, dass mehrere Instanzen einer Klasse erforderlich machen könnte, und immer dann, wenn es ein Szenario gibt, dass eine einzige Instanz zwingend notwendig macht.

            Sowohl für Deinen Übersetzer, als auch für Deine Datenbank-Zugriffsschicht gibt Szenarien, die durchaus mehrere Instanzen notwendig machen. Es gibt aber hingegen kein Szenario, wo sich jeweils zwei Instanzen der genannten Objekte gegenseitig in die Quere kommen können.

            Gruß Jens

            Kommentar


            • #7
              PHP-Code:
              class Translator extends Zend_Translate
              {
                  private static 
              $Instance false;

                  private function 
              __construct()
                  {
                          
              parent::__construct('ini''./language/en_US.ini''en');
                          
              self::$Instance $this;
                  }

                  public static function 
              GetInstance()
                  {
                      if (!
              self::$Instance)
                      {
                          
              self::$Instance = new Translator();
                      }
                      return 
              self::$Instance;
                  }

              Ist allerdings momentan nur eine leere Hülle für Zend_Translate
              Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

              Kommentar


              • #8
                Wozu um Himmels willen diese Zeile:

                PHP-Code:
                self::$Instance $this
                ?

                Gruß Jens

                Kommentar


                • #9
                  Stimmt, einmal die Instanz zuweisen reicht völlig aus...
                  Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                  Kommentar


                  • #10
                    Okay, danke Jens für die Ausführung. Ich sehe jetzt das Problem.

                    Zitat von lstegelitz Beitrag anzeigen
                    [PHP]class Translator extends Zend_Translate
                    Okay. Das funkioniert. Aber offensichtlich ist dieser Pattern von Zend nicht für Zend Translate vorgesehen.
                    Der Konstruktor von Zend_Translate muss public sein.
                    Was würdet ihr denn empfehlen, um den Translator an verschiedenen Stellen meiner Anwendung zu benutzen? Derzeit reiche ich die Instanz von Zend_Translate mit einem Registry-Pattern herum.

                    Kommentar


                    • #11
                      Also wenn du das Zend Framework nutzt kannst du auch die Zend_Registry nutzen. Damit kannst du ein Objekt in der Registry ablegen und überall in der Application drauf zugreifen.

                      Kommentar


                      • #12
                        Dependency Injection Pattern, Registry Pattern oder Du verwendest für Deinen Übersetzer einfach ne Aggregation in Form eines Konstruktor-Parameters, der dann in eine Instanzvariable überführt wird.

                        Gruß Jens

                        Kommentar


                        • #13
                          Zitat von Jens Clasen Beitrag anzeigen
                          Dependency Injection Pattern, Registry Pattern oder Du verwendest für Deinen Übersetzer einfach ne Aggregation in Form eines Konstruktor-Parameters, der dann in eine Instanzvariable überführt wird.
                          Bis auf Zend-Registry ist das alles Spanisch für mich. Werde dazu mal suchen.

                          Kommentar


                          • #14
                            Hättest Du auch früher sagen können, dass Du Singleton nur als Globals-Ersatz missbrauchen willst.
                            --

                            „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                            Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                            --

                            Kommentar


                            • #15
                              Eigentlich ist das nur ein bißchen Buzzword-Bingo. Zumindest Aggregation kennst Du sicherlich:

                              PHP-Code:
                              class Foo
                              {
                                private 
                              $translator;
                                
                                public function 
                              __construct(Zend_Translate $t)
                                {
                                  
                              $this->translator=$t;
                                  
                              // ...
                                
                              }

                              Die Beziehung zwischen Foo und Zend_Translate nennt man dann Aggregation.

                              Dependency Injection ist dann auch nur ne Registry mit etwas mehr Logik dahinter. Das Zugriffsszenario ist im wesentlichen das selbe, der Unterschied ist eigentlich nur, dass beim Registry Pattern Deine Objekte hinter String-Schlüsseln versteckt werden, und dass das Generieren der Registry-Inhalte in die Konfiguration verlegt wird, es also im Normalfall nicht mehr zur Implementierung gehört. (Wobei das Pattern selbst das durchaus zulässt.)

                              Ich hab schon Leute sagen hören, dass das Registry Pattern die einfachste und abstrakteste Form von Dependency Injection ist...

                              Gruß Jens

                              Kommentar

                              Lädt...
                              X