Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Marker-Interfaces

Einklappen

Neue Werbung 2019

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

  • #16
    Zitat von mYkon Beitrag anzeigen
    Wobei ich noch anmerken möchte, dass ein __construct in einem Interface nur gaaaaanz selten was verloren hat, oder?
    Wenn immer dieser in Stein gemeißelt werden soll.
    [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


    • #17
      Wenn du dynamisch Objekte erzeugen musst von unbekannten Klassen, dann ist für mich das Konzept des Interfaces in Frage gestellt.

      Kannst du mir ein Beispiel geben wo das unumgänglich ist? Mit einem Interface bediene ich eine BlackBox. Was interessieren mich seine Konstruktionspläne bzw. erzwungenen Abhängigkeiten?

      Meistens wird dann einfach der Konstruktor (weils halt so sein muss) gemäss Plan erstellt, die Werte in die Tonne geworfen, per Setter die richtigen Abhängigkeiten reingeladen und dann bei jeder Methode geprüft ob die Setter auch aufgerufen wurden... Alles sehr umständlich und widerspricht in meinen Augen dem Sinn der Interfaces.

      Kommentar


      • #18
        Zitat von mYkon Beitrag anzeigen
        Wenn du dynamisch Objekte erzeugen musst von unbekannten Klassen, dann ist für mich das Konzept des Interfaces in Frage gestellt.
        Da ist ja der Sinn das du vorgibst wie fremde Klassen auszusehen haben, damit du da nicht irgendein Objekt bekommst.

        Zitat von mYkon Beitrag anzeigen
        Kannst du mir ein Beispiel geben wo das unumgänglich ist? Mit einem Interface bediene ich eine BlackBox. Was interessieren mich seine Konstruktionspläne bzw. erzwungenen Abhängigkeiten?
        Du kannst nur durch 3rd Party Injection in fast allen Fällen Abhängigkeiten durch vollkommen andere Interfaces ersetzen.

        Zitat von mYkon Beitrag anzeigen
        Meistens wird dann einfach der Konstruktor (weils halt so sein muss) gemäss Plan erstellt, die Werte in die Tonne geworfen, per Setter die richtigen Abhängigkeiten reingeladen und dann bei jeder Methode geprüft ob die Setter auch aufgerufen wurden... Alles sehr umständlich und widerspricht in meinen Augen dem Sinn der Interfaces.
        Worst Practice.
        [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


        • #19
          Ich bleib dabei... Konstruktor im Interface = NoGo

          http://stackoverflow.com/questions/7...-in-interfaces
          http://artur.ejsmont.org/blog/conten...-are-the-rules

          Und da hats noch einige mehr davon im Netz. Bin bei grossen Frameworks (Symfony/Zend) auch noch nicht über so was gestolpert (vielleicht auch übersehen).

          Der Konstruktor interessiert nur beim Konstruierien. Wenn du was instanzierst, dann ja was konkretes, somit weisst du was dort rein muss sowieso. Gegen ein Interface konstruieren ist bei mir fail by design.

          Kommentar


          • #20
            Zitat von mYkon Beitrag anzeigen
            Ich bleib dabei... Konstruktor im Interface = NoGo

            http://stackoverflow.com/questions/7...-in-interfaces
            http://artur.ejsmont.org/blog/conten...-are-the-rules

            Und da hats noch einige mehr davon im Netz. Bin bei grossen Frameworks (Symfony/Zend) auch noch nicht über so was gestolpert (vielleicht auch übersehen).

            Der Konstruktor interessiert nur beim Konstruierien. Wenn du was instanzierst, dann ja was konkretes, somit weisst du was dort rein muss sowieso. Gegen ein Interface konstruieren ist bei mir fail by design.
            Wenn du ( also nicht dynamisch ) ein Objekt erzeugst, schaust du in den Constructor was der will.

            Damit auch eine Factory sich daran orientieren kann, besteht die Möglichkeit einen Constructor in ein Interfaces zu legen und ausnahmsweise nicht via Reflection die Signatur zu stalken.
            [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


            • #21
              Damit auch eine Factory sich daran orientieren kann, besteht die Möglichkeit einen Constructor in ein Interfaces zu legen und ausnahmsweise nicht via Reflection die Signatur zu stalken.
              Das würde mich wirklich interessieren, wie man über ein Interface ohne Reflection an die Contructor-Signatur dran kommt.

              vg
              jack
              -

              Kommentar


              • #22
                Zitat von jack88 Beitrag anzeigen
                Das würde mich wirklich interessieren, wie man über ein Interface ohne Reflection an die Contructor-Signatur dran kommt.

                vg
                jack
                Kommt man nicht, aber man vertraut eher einem Interfaces das man vorgegeben hat, als einer 3rd Party Klasse. Findest du also ein Interface das dein "Framework" definiert, wirst du dich an die von dir gestellten Vorgaben in der Factory halten, ganz egal welche Klasse drunter hängt.
                [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


                • #23
                  Ich bleib immer noch dabei... Aber für mich hat sichs erledigt. Mir ist schon klar, dass angenommen ich müsste Klassen instanzieren, die ich nicht kenne, dass ich dann auch lieber ein Interface hätte. Aber falls das auftauchen sollte irgendwo, würde ich 1. den Konstruktor leer lassen (Woher soll ich schon wissen, was das andere Teil für Dinge zwingend braucht, damit es funktioniert) und 2. mich schonmal gedanklich auf ein Refactoring einstellen.

                  - Ein Interface definiert was eine Klasse leisten muss, nicht "wie"/"mit was" sie es leisten muss
                  - Ich kann unmöglich wissen, was die Klasse benötigt, also instanziere ich sie auch nicht selbst
                  - Es führt unweiglicher zu schlechtem Code in der Klasse, wenn der Konstruktor ausgehebelt wird und ich mir zwingende Abhängigkeiten über Setters reinholen muss
                  - Ich kenne keine andere Sprache welche Konstruktor Interfaces erlaubt
                  - Ich kenne kein grösseres Framework, welches solche Interfaces bereitstellt

                  --> Da schreib ich lieber eine static factory welches ein Objekt mit Interface X liefern muss, als dass ich mir erlauben würde zu wissen wie ALLE Klassen die jemals dieses Interface implementieren werden, konstruiert werden müssten.

                  Kommentar


                  • #24
                    Ich würde ( oder tue ) aktuell auch nicht den Konstruktor in Blei gießen und nutze Interfaces die __construct(..) vorschreiben ( in meinen aktuellen Projekten ), aber ich wüsste schon Theoretisch Fälle bei denen das zweckmäßig wäre. Einer davon wäre halt eine Anwendungs-interne Factory die Anwendungs-Externe Objekte erzeugen sollte ohne dabei mit Abstrakten Klassen und/oder Reflection Methoden-Bingo zu spielen.

                    Aber gut, irgendwo geht das hier auch Richtung Offtopic.
                    [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


                    • #25
                      Ich glaube, php ist die einzige Sprache, wo sowas möglich ist.

                      Kommentar


                      • #26
                        Zitat von tr0y Beitrag anzeigen
                        Stell dir Folgendes Szenario vor:

                        PHP-Code:
                        interface Container
                        {
                           public function 
                        __construct(array $items = []);
                           public function 
                        has($item);
                           public function 
                        get($item);
                           public function 
                        set($item$content);
                           public function 
                        remove($item);

                        Ein simples Container Interface das vorgibt das der Container 4 Methoden und einen Constructor haben soll.

                        Nun möchtest du spezifizieren das es Mutable und Immutable Container gibt ( veränderbare und unveränderbare ):
                        PHP-Code:
                        interface ImmutableContainer extends Container {}
                        interface 
                        MutableContainer extends Container {} 
                        Diese Beiden Interfaces fungieren als Marker-Interfaces, da sie das Verhalten des Containers als veränderbar oder unveränderbar beschreiben. Du markierst hier nur den Container statt 2 separate Container-Interfaces aufzubauen bei dem der ImmutableContainer bspw. kein Remove() kennt und kein set(). Beide Container können jederzeit als "Container" identifiziert werden und das sie entsprechende Container-Methoden besitzen. Es ist aber auch möglich festzustellen ob der Container veränderbar oder unveränderbar ist.
                        wie würdest du die methoden set und remove bei dir in klassen, die den immutableContainer implementieren definieren? leerer body haben oder ne exception werfen?

                        ich bin noob, daher vielleicht blöde frage aber warum nicht einfach so?

                        PHP-Code:
                        interface Container
                        {
                           public function 
                        __construct(array $items = []);
                           public function 
                        has($item);
                           public function 
                        get($item);
                        }

                        interface 
                        ImmutableContainer extends Container {}

                        interface 
                        MutableContainer extends Container {
                           public function 
                        set($item$content);
                           public function 
                        remove($item);

                        können immer noch beide als container identifiziert werden.
                        ich dachte bei einem interface sollte man sich auch wirklich darauf verlassen können, dass die implementierenden klassen die methoden auch so implementieren dass wirklich das getan wird was man erwartet. also im falle von set und remove, dass dann auch immer was gesetzt oder entfernt wird und keine exception oder sonst was
                        liebe Grüße
                        Fräulein Dingsda

                        Kommentar


                        • #27
                          Container müssen nicht zwingend verschlossen sein, wenn sie unveränderlich sind. Sie können nachwievor erweiterbar sein. Versuchst du aber einen Wert zu ersetzen ( nicht anzufügen ) bekommst du eine Exception. Kommt darauf an wie du das implementieren willst. Ein Marker-Interfaces macht natürlich in der Form keinen Sinn wenn der Container verschlossen ist nachdem er initialisiert wurde. Dann würde deine Interface-Struktur mehr Sinn machen.
                          [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


                          • #28
                            danke für die erläuterung. hatte bei set erstmal direkt nur an das ersetzen von etwas vorhandenem gedacht. mein fehler
                            liebe Grüße
                            Fräulein Dingsda

                            Kommentar


                            • #29
                              Zitat von tr0y Beitrag anzeigen
                              Container müssen nicht zwingend verschlossen sein, wenn sie unveränderlich sind. Sie können nachwievor erweiterbar sein.
                              Das ist aber eine sehr schräge Auslegung von "immutable" ("unveränderlich"). Abgesehen davon, ändert eine Funktion mit dem Namen "remove" ganz sicher den Inhalt des Containers.

                              Die einzige Ausnahme, die ich mir im Falle eines "immutablen" Objekts vorstellen könnte, wäre, beim Aufruf einer "verändernden" Methode eine (modifizierte) Kopie des Originals zurückzugeben. Bspw. die Funktion sort() in macht das so (im Gegensatz zur PHP-Variante).

                              Zurück zu den Marker-Interfaces: Exceptions zu werfen, wenn eine legale (weil durch Interface oder Vererbung deklarierte) Methode aufgerufen wird, halte (nicht nur) ich für äußerst unfein.

                              Zitat von tr0y Beitrag anzeigen
                              Auch der PHP-Core nutzt Marker-Interfaces ( sie werden zwar als Interne Interfaces definiert und nicht explizit als solche beschrieben aber es sind reguläre Marker-Interfaces ). Bspw.: [man]Traversable[/man] auch hier wird eine Verhaltensbeschreibung gegeben ohne Methoden zu definieren.
                              Nein. Traversable ist ein Unfall, der sich aus Fehlentwicklungen in der PHP-Entwicklungsgeschichte ergab. Er ist keinesfalls als bewusste Design-Entscheidung entstanden. Siehe auch:
                              http://www.php.de/software-design/10...message_754374

                              Mir scheint, dass bisher niemand ein paar wirklich brauchbare Beispiele für sinnvoll einsetzbare Marker-Interfaces gefunden hat.

                              *update*
                              Eventuell relevant:

                              * http://www.onjava.com/pub/a/onjava/2...n_markers.html
                              * http://www.polyglotinc.com/DesignMarkers/
                              (via: [0] und [1])
                              Wenn man die Wurst schräg anschneidet, hält sie länger, weil die Scheiben größer sind.

                              Kommentar


                              • #30
                                Traversable ist ein Unfall, alles klar.. Der Satz hat in meinen Augen deinen gesamten Beitrag für absurd erklärt.

                                Mir scheint das du nie mit Marker Interfaces gearbeitet hast.
                                [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

                                Lädt...
                                X