Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Singleton - Verständnisfrage

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Singleton - Verständnisfrage

    Hallo,

    ich muss mich mal wieder als doof outen:

    Ich habe mir in der Literatur das Thema Singleton angesehen und auch das Forum über die Suchfunktion zu dem Thema durchsucht, bin mir aber nicht sicher ob ich die Absicht von Singletons unter PHP wirklich verstanden habe.

    Eine relativ klare Definition dazu lautet ja:
    "Es (das Singleton) stellt sicher, dass zu einer Klasse nur genau ein Objekt erzeugt werden kann, und ermöglicht einen globalen Zugriff auf dieses Objekt."

    Dumm gefragt: Wofür Singletons wenn es static gibt?

    Wenn ich alles richtig verstanden habe:

    1. Es gibt keine echten statischen Klassen in PHP (nur die Methoden und Attribute können statisch sein). Also könnte ich zumindest theoretisch mehrere Objekte erzeugen (der Sinn sei dahingestellt).

    2. Das Singleton hat einen (einmalig verwendbaren) Constuctor im Gegensatz statischen Methoden/ Attributen.

    3. Static Methoden/ Attribute können in _jeder_ Klasse ohne weiteres verwendet werden. Ein Singleton muss ich in anderen Klassen explizit als "neues" Objekt angelegt werden - es verweist aber dennoch immer auf das _Eine_ Objekt.


    1) ja [ ] nein [ ] entsetztes Schreiben ob der Frage [ ]

    2) ja [ ] nein [ ] entsetztes Schreiben ob der Frage [ ]

    3) ja [ ] nein [ ] entsetztes Schreiben ob der Frage [ ]

    Vielen Dank im Voraus!

  • #2
    zumindest 3 ist schonmal klar ....

    Der/ Das Singleton ist wie der Highlander - es kann nur eine Instanz geben. Damit entfällt dein Ansatz von wegen "in jedem Objekt neu anlegen" - das geht nämlich gar nicht.

    2 seh ich ebenso - es geht nicht um den Constructor - die ganze Klasse darf genau 1 mal in ein Object instanziiert werden - zumindest so lange das Script läuft - bei einem neuen Request kannst du logischerweise wieder eins davon anlegen. - deswegen nehmen MANCHE Programmierer Singleton Patterns für ihre Datenbank-Klasse. Es wird dann in allen Programm-teilen für sämtliche Datenbank-Zugriffe immer nur dieses eine Object verwendet

    1) statische Methoden stecken nicht im instanziierten Object - für die statischen Methoden brauchst du nicht mal eine Instanz ...

    und nun zum Abschluss 0) obwohl deine Anleitung genau das beschreibt, sollst du Singleton NICHT ALS GLOBALS-ERSATZ NEHMEN ..
    Global ist und bleibt unsicher und sollte allgemein nicht benutzt werden.
    "Irren ist männlich", sprach der Igel und stieg von der Drahtbürste [IMG]http://www.php.de/core/images/smilies/icon_lol.gif[/IMG]

    Kommentar


    • #3
      Dumm gefragt: Wofür Singletons wenn es static gibt?
      Es (das Objekt) ist ja nicht static! Nur die Funktion, die das Objekt erzeugt und die Instanz liefert ist static.
      Der Konstruktor ist auch mehrfach verwendbar, wird aber nur einmal aufgerufen und zwar von der statischen Methode, die das Objekt erzeugt. Idealerweise ist der Konstruktor geschützt, damit eben keiner von ausserhalb einfach ein neues Objekt erzeugen kann.
      PHP-Code:
      class MySingleton {
        protected 
      $_instance null// geschützte Instanz

        
      protected __construct() { // geschützter Konstruktor - kann NICHT von aussen aufgerufen werden
          // Instanz mit Werten belegen
        
      }

        public static 
      create() {
          if (
      $this->_instance == null
            
      $this->_instance = new MySingleton(); // nur 1 mal erzeugen!
          
      return $this->_instance// wenn schon erzeugt, nur Referenz zurückliefern
        
      }
      }

      $inst = new MySingleton(); // FEHLER! 
      $inst MySingleton::create(); // So gehts... 
      Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

      Kommentar


      • #4
        Zitat von eagle275 Beitrag anzeigen
        Der/ Das Singleton ist wie der Highlander - es kann nur eine Instanz geben. Damit entfällt dein Ansatz von wegen "in jedem Objekt neu anlegen" - das geht nämlich gar nicht....
        Ist schlecht von mir ausgedrückt - liegt wahrscheinlich an meiner Hilflosigkeit

        Ich habe ein Singleton geschrieben und rufe es erstmals auf:

        $Obj = Klasse::singleton('42');
        $Obj->tueWichtiges('und danke fuer den Fisch');

        $WasGanzAnderes = new GanzGanzAndereKlasse();
        $WasGanzAnderes->tueAuchWasMit("Handtuch");

        _Innerhalb_ der vollkommen anderen Klasse "class GanzGanzAndereKlasse(){...}" möchte ich nun das Singleton nutzen: Dort habe ich ja aber $Obj nicht zur Verfügung, sondern muss mir ja meine eigene interne "Instanz" definieren, die allerdings auf das originale, das "Eine" Singleton verweist?

        So sah es bei meinen Tests jedenfalls aus.

        Kommentar


        • #5
          Zitat von lstegelitz Beitrag anzeigen
          Der Konstruktor ist auch mehrfach verwendbar, wird aber nur einmal aufgerufen und zwar von der statischen Methode, die das Objekt erzeugt.
          Bedeutet das nicht, kleinlich und zugegeben penibel gesehen, dass der Construcor nur einfach, einmalig verwendbar ist? Nach der ersten Verwendung wird er ja eben nicht mehr aufgerufen, sondern ist gesperrt.

          Zitat von lstegelitz Beitrag anzeigen
          Idealerweise ist der Konstruktor geschützt, damit eben keiner von ausserhalb einfach ein neues Objekt erzeugen kann.
          Auch ganz kleinlich , weil es mir ums tiefere Verständnis geht: Der Schutz des Constructors ist nicht nur "idealerweise" geschützt, sondern Grundlage des Singletons?

          Kommentar


          • #6
            Zitat von Neither Beitrag anzeigen
            Bedeutet das nicht, kleinlich und zugegeben penibel gesehen, dass der Construcor nur einfach, einmalig verwendbar ist? Nach der ersten Verwendung wird er ja eben nicht mehr aufgerufen, sondern ist gesperrt.
            Er ist mehrfach verwendbar, wird aber nur einmal aufgerufen. Stellt man das nicht sicher (ungeschützter Konstruktor) könnte man weitere Objekte erzeugen - womit dann das Singleton keines mehr wäre...

            Zitat von Neither Beitrag anzeigen
            Auch ganz kleinlich , weil es mir ums tiefere Verständnis geht: Der Schutz des Constructors ist nicht nur "idealerweise" geschützt, sondern Grundlage des Singletons?
            Jain. Grundlage ist, das nur ein Objekt erzeugt wird - wie man das genau erreicht, ist dabei nicht so wichtig:

            PHP-Code:
            class MySingleton {
              protected 
            $_instance;

              public 
            __construct($magic) {
                if (
            $magic != 'my_magic_value'
                  throw new 
            Exception('magic value exception');
              }

              public static 
            create() {
                if (
            $this->_instance == null)
                  
            $this->_instance = new MySingleton('my_magic_value');
                return 
            $this->_instance;
              }

            Zugegeben: In PHP funktioniert sowas nicht so dolle, weil jederman in den Quellcode schauen kann. Bei kompilierten Sprachen kann man es aber auch so machen (die Klasse liegt dann nur noch als kompilierte Library vor und niemand kann einfach so den magischen Wert auslesen)
            Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

            Kommentar


            • #7
              1. Es gibt keine echten statischen Klassen in PHP (nur die Methoden und Attribute können statisch sein).
              Richtig
              Also könnte ich zumindest theoretisch mehrere Objekte erzeugen (der Sinn sei dahingestellt).
              Theoretisch, wenn es keine Singleton-Implementierung benutzt. Aber wir reden hier über ST.
              2. Das Singleton hat einen (einmalig verwendbaren) Constuctor im Gegensatz statischen Methoden/ Attributen.
              Nein. Den Konstruktor kannst Du nicht einschränken. Ein ST stellt auf andere Art und Weise sicher, dass eine Mehrfachinstanziierung unmöglich ist. Üblicherweise über statische Instanzverwaltung und private Konstruktoren.
              3. Static Methoden/ Attribute können in _jeder_ Klasse ohne weiteres verwendet werden. Ein Singleton muss ich in anderen Klassen explizit als "neues" Objekt angelegt werden - es verweist aber dennoch immer auf das _Eine_ Objekt.
              Üblicherweise wird die Methode "Hole verwaltete Instanz" statisch aufgerufen, die bei Bedarf (beim Erstaufruf) auch die Instanz erzeugt.
              Das wichtigste an ST ist, dass mit _Objekten_ gearbeitet wird. Statische Methoden können u. U. nicht dynamisch genutzt werden, Du kannst eine Klasse auch nicht als Parameter übergeben, dabei TypeHintin verwenden etc. Und auch wenn ST es ermöglicht, ist es oftmals schlechter Stil, das Objekt in einem Methoden/Funktionskontext zu "holen", statt einen Parameter zu verwenden. Vgl. Abhängigkeiten und DI-Pattern.
              [COLOR="#F5F5FF"]--[/COLOR]
              [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
              „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
              [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
              [COLOR="#F5F5FF"]
              --[/COLOR]

              Kommentar


              • #8
                Überlicherweise holt man sich eine Singleton-Instanz per getInstance oder ähnlich benamst. Eine create-methode wie von Isteglitz in #3 impliziert eher eine Factory. Das Klonen des Singletons sollte auch verboten sein.

                Ab php 5.3 kann man dann auch per late static binding vererben, einen sehr hübschen Blogeintrag vom 'phpgangsta' mit Erklärungen findest du hier.

                Viele Grüße


                Basti
                I like cooking my family and my pets.
                Use commas. Don't be a psycho.
                [URL="http://jscouch.de"]Blog[/URL] - [URL="http://coverflowjs.github.io/coverflow/"]CoverflowJS[/URL]

                Kommentar


                • #9
                  Zitat von nikosch Beitrag anzeigen
                  Nein. Den Konstruktor kannst Du nicht einschränken. Ein ST stellt auf andere Art und Weise sicher, dass eine Mehrfachinstanziierung unmöglich ist.
                  Dadurch wird mir einiges klarer. Liegt wohl daran, dass ein Singleton kein echtes Sprachkonstrukt ist?

                  Zitat von nikosch Beitrag anzeigen
                  ...
                  Üblicherweise wird die Methode "Hole verwaltete Instanz" statisch aufgerufen, die bei Bedarf (beim Erstaufruf) auch die Instanz erzeugt.
                  Das wichtigste an ST ist, dass mit _Objekten_ gearbeitet wird. Statische Methoden können u. U. nicht dynamisch genutzt werden, Du kannst eine Klasse auch nicht als Parameter übergeben, dabei TypeHintin verwenden etc. Und auch wenn ST es ermöglicht, ist es oftmals schlechter Stil, das Objekt in einem Methoden/Funktionskontext zu "holen", statt einen Parameter zu verwenden. Vgl. Abhängigkeiten und DI-Pattern.
                  Bei meinen Versuchen habe ich in anderen Klassen das Singleton derart aufgerufen:

                  PHP-Code:
                  class ganzGanzAndereKlasse{

                      private 
                  $Obj;

                      function 
                  __construct()
                      {
                          ...

                          
                  $this->Obj Klasse::singleton();
                          
                  $this->Obj->tueWas('WasAuchImmer');
                      }
                   ... 
                  Meinst Du mit 'Methode "Hole verwaltete Instanz"' die statische Methode beim Erschaffen (hier "singleton" genannt) oder gibt es noch etwas anderes?

                  Kommentar


                  • #10
                    Zitat von rudygotya Beitrag anzeigen
                    Überlicherweise holt man sich eine Singleton-Instanz per getInstance oder ähnlich benamst.
                    Geht es da nur um die Benamung oder wäre die auch inhaltlich anders aufgebaut?


                    Zitat von rudygotya Beitrag anzeigen
                    Eine create-methode wie von Isteglitz in #3 impliziert eher eine Factory.
                    Wikipedia sagt dazu
                    "In object-oriented computer programming, a factory is an object for creating other objects. It is an abstraction of a constructor, and can be used to implement various allocation schemes. For example, using this definition, singletons implemented by the singleton pattern are formal factories."

                    Heißt das nicht, dass sich das (Factory - Singleton) in diesem Zusammenhang _nicht_ widerspricht?

                    Kommentar


                    • #11
                      Ging nur um die Benamsung. Ja, das widerspricht sich, daher auch der Einwand

                      Grüße


                      Basti
                      I like cooking my family and my pets.
                      Use commas. Don't be a psycho.
                      [URL="http://jscouch.de"]Blog[/URL] - [URL="http://coverflowjs.github.io/coverflow/"]CoverflowJS[/URL]

                      Kommentar


                      • #12
                        Zitat von rudygotya Beitrag anzeigen
                        Ging nur um die Benamsung. Ja, das widerspricht sich, daher auch der Einwand...
                        Ich glaube jetzt klingelt es so langsam

                        Kommentar


                        • #13
                          Ich wollte mich noch bei rudygotya, nikosch, lstegelitz, eagle275 (Reihenfolge ohne Wertung ) für die für mich sehr hilfreichen Antworten ganz herzlich bedanken!

                          DANKE! Ihr habt mir sehr weitergeholfen!

                          Kommentar


                          • #14
                            @istegelitz:

                            das wird nix

                            PHP-Code:
                            class MySingleton 
                              protected 
                            $_instance

                              public 
                            __construct($magic) { 
                                if (
                            $magic != 'my_magic_value')  
                                  throw new 
                            Exception('magic value exception'); 
                              } 

                              public static 
                            create() { 
                                if (
                            $this->_instance == null
                                  
                            $this->_instance = new MySingleton('my_magic_value'); 
                                return 
                            $this->_instance
                              } 

                            eher

                            PHP-Code:
                            class MySingleton 
                              protected static 
                            $_instance

                              public function 
                            __construct($magic) { 
                                if (
                            $magic != 'my_magic_value')  
                                  throw new 
                            Exception('magic value exception'); 
                              } 

                              public static final function 
                            create() { 
                                if (
                            self::$_instance == null
                                  
                            self::$_instance = new MySingleton('my_magic_value'); 
                                return 
                            self::$_instance
                              }


                            a) statische methoden können nicht auf den objekt-stamm eines Objekts zugreifen, weil statischer Aufruf
                            b) functions sollten man als solche definieren, "public static create()" ist keine valide definition.
                            [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                            Kommentar


                            • #15
                              Ja, hast Recht... static und $this verträgt sich nicht... war zu schnell runtergetippt/abgeschickt. Danke für die Korrektur
                              Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                              Kommentar

                              Lädt...
                              X