MB: Static in MVC-Architektur?

Guten Abend,

Frage: Wo ist STATIC oder FINAL Methoden und Variablen Sinvoll in einer simplen Webseite mit MVC-Struktur.

In Komplexen Strukturen kann ich mir das gut vorstellen aber in einer einfachen MVC-Architektur nicht. Wahrscheinlich habe ich den Zweck der beiden classen funktionen - heißt das so? - nicht richtig verstanden, kenne aber ihre funktionsweise.

vlg MB

  1. Moin!

    Frage: Wo ist STATIC oder FINAL Methoden und Variablen Sinvoll in einer simplen Webseite mit MVC-Struktur.

    Nirgends. Jedenfalls nicht dort, wo du vermutest, dass sie sinnvoll sein könnten.

    In Komplexen Strukturen kann ich mir das gut vorstellen aber in einer einfachen MVC-Architektur nicht. Wahrscheinlich habe ich den Zweck der beiden classen funktionen - heißt das so? - nicht richtig verstanden, kenne aber ihre funktionsweise.

    Soll das heißen, du siehst in komplexen Architekturen Verwendungsmöglichkeiten für static oder final?

    Ok, bei final mag die Lage eventuell noch etwas anders gelagert sein. Final-Variablen gibts nicht, und finale Methoden könnten eine sinnvolle Wahl sein, um Vererbung zu verhindern - was wiederum eine durchaus sinnvolle Methode zum Erziehen von Entwicklern ist, die beim Lesen von Tutorials nur "OOP ist Vererben" verstanden haben. Vererbung ist der schlechtere Part von OOP und wird, genau wie Singletons, noch viel zu sehr propagiert.

    Was static angeht: Es gibt bei mir nur einen Platz dafür: In Factory-Methoden dedizierter Factory-Klassen, die man NICHT instanziert. Irgendwo müssen die Bauvorschriften zum Zusammenbau von Objektbäumen gekapselter Pakete ja gelagert werden, und derartige aufrufbare Static-Methoden sind tatsächlich am kompatibelsten zu allen möglichen Dependency-Injection-Variationen: Wenn man das selbst per Hand macht, ist ein Factory-Call genauso simpel, wie die Einbindung desselben als callable in einen DI-Container.

    Grüße Sven

    1. Vererbung ist der schlechtere Part von OOP

      Warum soll Vererbung schlecht sein und was ist deiner Ansicht nach der bessere Teil?

      1. Hallo,

        ich bin nicht Sven, aber ein paar Einblicke kann ich auch geben.

        Vererbung ist der schlechtere Part von OOP

        Warum soll Vererbung schlecht sein und was ist deiner Ansicht nach der bessere Teil?

        Das Problem an Vererbung ist, dass es zwei Klassen direkt und hart miteinander koppelt ohne eine Möglichkeit, diese in irgendeiner Form voneinander zu trennen. Es gibt Einsatzgebiete, wo dies sinnvoll ist, aber diese sind seltener als man zuerst denkt. Klassisches Beispiel wie man Vererbung nicht nutzen sollte: Code-Wiederverwendung über Vererbung statt über Delegation.

        Der bessere Teil kommt, wenn man Objektbäume zusammenstöpselt, so dass einzelne Teilalgorithmen (Klassen) austauschbar sind und sie zusammengenommen die Logik ergeben, die du haben willst. Der Vorteil liegt ganz klar in der einfachen Testbarkeit von kleinen Klassen und durch die Klassenzusammenstellung kann man relativ bequem (entweder zur Compile-Time, etwa beim Testen oder zur Laufzeit durch eine andere Konfiguration von Factories) Code austauschen - etwas, was z.B. bei Vererbung nicht funktioniert.

        Viele Grüße, Matti

        1. nabend Matti

          Das Problem an Vererbung ist, dass es zwei Klassen direkt und hart miteinander koppelt ohne eine Möglichkeit, diese in irgendeiner Form voneinander zu trennen.

          sehe ich genauso und habe ins geheim gehoft das das nur anfängerverständnis ist.

          Es gibt Einsatzgebiete, wo dies sinnvoll ist, aber diese sind seltener als man zuerst denkt.

          zb?

          Grüße MB

          1. Moin!

            Das Problem an Vererbung ist, dass es zwei Klassen direkt und hart miteinander koppelt ohne eine Möglichkeit, diese in irgendeiner Form voneinander zu trennen.

            sehe ich genauso und habe ins geheim gehoft das das nur anfängerverständnis ist.

            Es gibt Einsatzgebiete, wo dies sinnvoll ist, aber diese sind seltener als man zuerst denkt.

            zb?

            Wenn es tatsächlich um Code geht, der untrennbar zu einem Thema gehört, bzw. zueinander gehörend betrachtet wird. Beispielsweise wird man tausendundeinen unterschiedlichen Validator für Formularwerte erfinden können, aber die grundsätzliche Infrastruktur eines Pakets, dass sich mit Validierung beschäftigt, könnte jeder einzelne Validator von einer abstrakten Klasse erben, sofern es dabei um mehr als nur den gemeinsamen Konstruktor geht.

            Dinge, die ich auch über Vererbung lösen würde: Eine Klasse hat den Code und protected properties mit bestimmten Settings, und eine davon erbende Klasse ändert nur an diesen Settings.

            Aber tatsächlich sollte man viel weniger auf Vererbung setzen, und mehr auf Zusammensetzung/Komposition. Das gilt vermutlich auch für das Validator-Beispiel: Was bringt es einem, einen Validator zu schreiben, der zwingend von einer vorliegenden abstrakten Klasse deren Infrastruktur-Implementierung erben muss, wenn man die gar nicht braucht? Als Autor des Validatorpakets ist es eventuell sinnvoll, nicht alles doppelt zu schreiben, aber andererseits ist der Nutzen für den Rest der Welt größer, wenn man auch nur einen einzelnen Validator benutzen könnte, ohne Zeugs drumrum. Bei Vererbung ist "ohne Zeugs drumrum" nicht machbar.

            Grüße Sven

            1. Das Problem an Vererbung ist, dass es zwei Klassen direkt und hart miteinander koppelt ohne eine Möglichkeit, diese in irgendeiner Form voneinander zu trennen.

              Das ist nicht das Problem, das ist eher Sinn der Sache. Eine Unterklasse erweitert die Funktionalität ihrer Elternklassen. Die Klassen gehören zusammen, da sollte es keinen Grund geben, sie trennen zu wollen, mehr noch: Idealerweise lassen sie sich gar nicht trennen, weil sie funktional aufeinander aufbauen.

              Was bringt es einem, einen Validator zu schreiben, der zwingend von einer vorliegenden abstrakten Klasse deren Infrastruktur-Implementierung erben muss, wenn man die gar nicht braucht?

              Dann ist die Elternklasse oder die ganze Struktur falsch aufgebaut. Das ist aber kein Problem der Vererbung, das ist ein Problem schlechter Programmierung (oder von Erbsenzählerei – brauche ich zwei oder drei von zehn Methoden nicht, ist nicht gleich die ganze Klasse schlecht). Programmteile, die sich um zu viele Sachen kümmern, gab es schon vor Klassen und Objekten, da waren es dann halt Funktionen mit einem Dutzend Parametern.

              Ihr schiebt schlechte Programmierung in Form von nicht durchdachten, schlecht strukturiertem Programmaufbau der Vererbung in die Schuhe.

              ohne Zeugs drumrum.

              Derselbe schlechte Programmierer, der alles erschlagenden Klassen bastelt, wird ein Konvolut an Funktiönchen fabrizieren, das so unübersichtlich ist, dass eines nicht zum anderen passt.
              Mir fällt da als besonders abschreckendes Beispiel spontan PHP mit seinem Irrwitz an Tausenden (?) eingebauter Funktionen ein. Da kann man sich einzeln raussuchen, was man braucht, ohne "Zeugs" drumherum. Aber ist das wirklich pauschal besser, Vererbung pauschal schlechter? Ich denke nicht. Es kommt auf Bedarf und Umsetzung an. Mist kann man mit jeder Technik bauen, das macht keine per se schlechter.

              1. Hi,

                Derselbe schlechte Programmierer, der alles erschlagenden Klassen bastelt, wird ein Konvolut an Funktiönchen fabrizieren, das so unübersichtlich ist, dass eines nicht zum anderen passt.
                Mir fällt da als besonders abschreckendes Beispiel spontan PHP mit seinem Irrwitz an Tausenden (?) eingebauter Funktionen ein. Da kann man sich einzeln raussuchen, was man braucht, ohne "Zeugs" drumherum. Aber ist das wirklich pauschal besser, Vererbung pauschal schlechter?

                nein, ein pauschales "besser" oder "schlechter" kann man sicher nicht attestieren.

                Schlecht finde ich allerdings, wenn man eine Bibliothek oder eine Klasse mit vielen Abhängigkeiten einbindet, davon aber nur einen kleinen Bruchteil wirklich nutzt. Denn dann übersteigt der Aufwand, die ganze Bibliothek oder Klassenhierarchie richtig und funktionstüchtig zu initialisieren, unter Umständen den Aufwand, den man durch Nutzung von fertigem Code einspart. Das ist der Hauptgrund, warum ich oft den Einsatz fertiger Bibliotheken oder Frameworks ablehne und stattdessen das bisschen, was ich davon eigentlich bräuchte, selbst schreibe. Das ist nicht das NIH-Syndrom (obwohl ich zugebe, dass das bei mir auch manchmal mit hineinspielt), sondern eine reine Aufwand/Nutzen-Abschätzung.
                Und dazu kommt ja immer noch der Aufwand, dass man sich zuerst einmal in die Struktur und das Konzept der verwendeten Bibliothek hineinfuchsen muss. Das kann je nach Qualität der Dokumentation (die leider in vielen Fällen gegen Null geht) mehrere Tage zusätzlichen Aufwand bedeuten.

                Es kommt auf Bedarf und Umsetzung an. Mist kann man mit jeder Technik bauen, das macht keine per se schlechter.

                Absolut richtig.

                So long,
                 Martin

                --
                Bei der Umsetzung von guten Ideen hapert es meist viel mehr an der Wolle als an der Könne.
    2. nabend Sven,

      Soll das heißen, du siehst in komplexen Architekturen Verwendungsmöglichkeiten für static oder final?

      jop zb in Shopsnach MVC-Architektur

      Was static angeht: Es gibt bei mir nur einen Platz dafür: In Factory-Methoden dedizierter Factory-Klassen, die man NICHT instanziert.

      Ok, was sind das diese Begriffe?

      schönen Anend MB

      1. Moin!

        nabend Sven,

        Soll das heißen, du siehst in komplexen Architekturen Verwendungsmöglichkeiten für static oder final?

        jop zb in Shopsnach MVC-Architektur

        Gibts dafür Beispiele? Ich bin ziemlich sicher, dass ich gute Gegenargumente habe, GERADE wenn es komplex wird.

        Was static angeht: Es gibt bei mir nur einen Platz dafür: In Factory-Methoden dedizierter Factory-Klassen, die man NICHT instanziert.

        Ok, was sind das diese Begriffe?

        Ich verstehe die Frage nicht.

        Grüße Sven

  2. Tach!

    Frage: Wo ist STATIC oder FINAL Methoden und Variablen Sinvoll in einer simplen Webseite mit MVC-Struktur.

    static und final haben jeweils ihre eigenen Einsatzgebiete. Man kann sie nicht wirklich gemeinsam auf Sinnhaftigkeit untersuchen.

    In Komplexen Strukturen kann ich mir das gut vorstellen aber in einer einfachen MVC-Architektur nicht.

    Es ist auch nicht sinnvoll, die Komplexität einer Anwendung als Kriterium für ihren Einsatz heranzuziehen.

    Wahrscheinlich habe ich den Zweck der beiden classen funktionen - heißt das so? - nicht richtig verstanden, kenne aber ihre funktionsweise.

    Es sind Schlüsselwörter. Die haben zwar eine Funktion (Aufgabe) im Bereich von Klassen, aber unter einer Klassen-Funktion versteht man eher eine Methode, also eine zu einer Klasse gehörenden Funktion (Unterprogramm). Um zwischen Funktion (Aufgabe) und Funktion (Unterprogramm) zu unterscheiden, nehme ich für ersteres lieber das Wort Funktionalität. Ich würde aber static und final nicht als Klassenfunktionalität bezeichnen wollen, weil es keine Aufgaben von Klassen sind, sondern Dinge in Klassen beeinflussen. Sie werden deshalb als Modifizierer (modifier) bezeichnet. Es ist aber in der Praxis nicht besonders wichtig, diesen Begriff zu kennen. Du kannst immer sagen: "Die Klasse/Methode/Eigenschaft ist (als) public/private/final/static (gekennzeichnet)", und jeder wird dich verstehen (im Englischen: "... is marked as ...").

    Der Zweck von static ist, Methoden und Eigenschaften zu Klassen hinzuzufügen, die man verwenden kann, ohne Instanzen der Klassen erstellen zu müssen. Eine bedeutende Eigenschaft von static properties ist, dass sie sozusagen Singletons sind. Weil sie an die Klasse gebunden sind, bleiben sie stets bei dieser und werden auch nicht beim Instantieren von Objekten dieser Klasse vervielfältigt. Ob der Einsatz eines Singleton an sich sinnvoll ist oder nicht, steht auf einem anderen Blatt.

    Eine typische Anwendung von statischen Methoden ist die Math-Klasse, wie sie anderenorts zu finden ist. In PHP sind die Mathematik-Funktionen in "normalen" Funktionen zu finden.

    final hat in PHP keinen besonders gesteigerten Sinn. Es zeigt mehr oder weniger nur dem Verwender an, dass man diese Klasse nicht beerben soll oder eine damit gekennzeichnete Methode nicht überschreiben soll. Da PHP meist als Code vorliegt, könnte man das Schlüsselwort auch einfach entfernen und es dann trotzdem tun. Damit ist sein Nutzen ziemlich begrenzt. Lediglich bei nicht als Code gelieferten Dingen (in PHP eingebaute Klassen und verschlüsselter Code von kommerziellen Anbietern) ist das final nicht entfernbar. Und wenn man sich dafür entscheidet, fremden Code unverändert einzubinden, um die Updatefähigkeit nicht zu gefährden. Es gibt auch das Decorator-Pattern, um die Funktionalität anzupassen, ohne dass man erben muss, und dann kann man auch um das final drumherumarbeiten.

    Nochmal meine Empfehlung aus dem anderen Thread: Schau dir die anderen Frameworks an, da findest du Beispiele auch für den Einsatz von static und vielleicht auch final. Oder aber du findest nichts oder nicht viel, weil ihr Einsatz als nicht sinnvoll oder gar störend erachtet wurde. Schau eher, wie andere bestimmte Probleme lösen, und weniger nach Einsatzgebieten für bestimmte Konstrukte. Denn das ist, was du in der Praxis machst: Lösungen für Aufgabenstellungen erarbeiten und nicht Einsatzgebiete für Code-Konstrukte und Programmiermuster suchen.

    dedlfix.

    1. nabend dedlfix,

      ersteinmal recht herzlichen Dank für deine ausformulierte verständliche Hilfestellung.

      Nochmal meine Empfehlung aus dem anderen Thread: Schau dir die anderen Frameworks an, da findest du Beispiele auch für den Einsatz von static und vielleicht auch final.

      Wenn du wüstest wie gerne ich deinen rat folgen würde. Aber Dazu brauche ich viel Zeit die ich mir sehr gerne nehme aber nicht hab :/.

      Jetzt in dieser Lernsituation ist außerhalb ein kleines MVC in PHP zu programmieren nur utopie. In den Sommerferien hätte ich "etwas" mehr Zeit.

      Wünsch dir n schönen Abend, MB

  3. hi

    Frage: Wo ist STATIC oder FINAL Methoden und Variablen Sinvoll in einer simplen Webseite mit MVC-Struktur.

    Unabhängig v. MVC: Über static Variablen innerhalb einer Funktion lassen sich die Rückgabewerte schön cachen (wenn die Funktion mehrmals aufgerufen wird).

    Wenn es jedoch eine Methode ist, kann solch Cachen auch über ein Attribut der Instanz erfolgen.

    Rom, verschiedene Wege...

    1. Tach!

      Wenn es jedoch eine Methode ist, kann solch Cachen auch über ein Attribut der Instanz erfolgen.

      Verwende doch lieber den Begriff Eigenschaft (Property). In PHP ist es nicht üblich, dazu Attribut zu sagen. (In C# ist ein Attribut sogar etwas ganz anderes als eine Property.)

      dedlfix.

      1. In C# ist ein Attribut sogar etwas ganz anderes als eine Property.

        Wusste ich nicht, ist nicht meine Schuld und ist mir auch egal.

        1. Hallo,

          Wusste ich nicht,

          Das macht nix. Kannst du bei Bedarf ändern.

          ist nicht meine Schuld

          das hat dir auch niemand vorgeworfen. Kein Änderungsbedarf.

          und ist mir auch egal.

          Das ist das Problem und da wünschen wir uns alle hier, dass du den Änderungsbedarf einsiehst und abstellst.

          Gruß
          Kalk

          1. das hat dir auch niemand vorgeworfen. Kein Änderungsbedarf.

            und ist mir auch egal.

            Das ist das Problem und da wünschen wir uns alle hier, dass du den Änderungsbedarf einsiehst und abstellst.

            Na also: Kein Änderungsbedarf, siehe obenstehend. Sehe ich auch so.

            Also, wegen irgendwelchen Bezeichnern rumstreiten, das ist wirklich das Allerletzte, zumal aus dem Kontext klar hervorgeht um was es sich handelt. Und ja, lt. meiner Schule ist Attribut == Eigenschaft im Kontext von Klassen oder Instanzen. Siehe auch Eric Foster Johnson, Perl-Module, MITP Verlag.

            PS: Jemanden um was bitten oder sich was wünschen sind zwei verschiedene Dinge.

    2. Hallo,

      Frage: Wo ist STATIC oder FINAL Methoden und Variablen Sinvoll in einer simplen Webseite mit MVC-Struktur.

      Unabhängig v. MVC: Über static Variablen innerhalb einer Funktion lassen sich die Rückgabewerte schön cachen (wenn die Funktion mehrmals aufgerufen wird).

      Wobei ich ein cachen von Rückgabewerten dann doch lieber über einen Cache-Proxy erledigen würde anstatt durch das Objekt selber. Das hat den Vorteil, dass man die Caching-Strategie (pro Klasse oder Instanz) viel einfach auswechseln kann und das der Business-Code vom Thema Caching entkoppelt ist, was es einfacher zu testen macht.

      Viele Grüße, Matti

      1. Wobei ich ein cachen von Rückgabewerten dann doch lieber über einen Cache-Proxy erledigen würde anstatt durch das Objekt selber. Das hat den Vorteil, dass man die Caching-Strategie (pro Klasse oder Instanz) viel einfach auswechseln kann und das der Business-Code vom Thema Caching entkoppelt ist, was es einfacher zu testen macht.

        kannst mal n beispiel machen??? Nie gesehen oder ähnlich aber der Begriff wäre mir nicht geläufig

        1. Moin!

          Wobei ich ein cachen von Rückgabewerten dann doch lieber über einen Cache-Proxy erledigen würde anstatt durch das Objekt selber. Das hat den Vorteil, dass man die Caching-Strategie (pro Klasse oder Instanz) viel einfach auswechseln kann und das der Business-Code vom Thema Caching entkoppelt ist, was es einfacher zu testen macht.

          kannst mal n beispiel machen??? Nie gesehen oder ähnlich aber der Begriff wäre mir nicht geläufig

          interface MyTask {
              public function doSomething($param);
          }
          
          class MyTaskImpl implements MyTask {
              public function doSomething($param) {
                  sleep(1000); // braucht ewig
                  return $param.$param;
              }
          }
          
          class MyTaskCachingProxy implements MyTask {
              public function __construct(MyTask $task) {
                  $this->innerTask = $task;
              }
          
              public function doSomething($param) {
                  return $this->innerTask->doSomething($param);
              }
          }
          

          Der CachingProxy macht im Moment noch kein Caching - aber man kann die Logik, um einen Speicher anzubinden, auf Vorkommen eines Speicherwertes je nach $param zu durchsuchen, im Erfolgsfall das Auslesen und zurückgeben des gecachten Wertes, im Mißerfolgsfall das Aufrufen der Originalfunktion, das Abfangen des Rückgabewerts mit Abspeichern, viel besser auslagern, wenn man sie nicht zusammen mit der fachlichen Funktionalität in eine Klasse kippt.

          Bonuspunkt: Wenn irgendwas mit dem Cache nicht funktioniert, lässt man den Proxy mal weg und schaut, ob es dann immer noch nicht funktioniert: Wenn das Problem bleibt, liegt es in der eigentlichen Fachlogik, wenn es dann verschwunden ist, hat man vermutlich ein Problem in der Cachelogik.

          Und weil sowohl Fachlogik als auch Cachelogik komplex werden dürften, will man das nicht vermischen.

          Es gibt übrigens nur zwei Bibliotheken für PHP, die Caching einigermaßen vernünftig für beide Aspekte umsetzen: Zend_Cache aus dem Zend Framework 1, und Zend\Cache aus dem Zend Framework 2. Alle anderen üblichen Verdächtigen, wie Symfony oder Doctrine, haben lediglich einen Layer für die Abstraktion des Storage, nicht aber für das Implementieren einer Proxy-Klasse mit Abfangen der Rückgaben (nicht vergessen: auch ECHO ist eine Art Rückgabe).

          Grüße Sven

    3. hi

      Unabhängig v. MVC: Über static Variablen innerhalb einer Funktion lassen sich die Rückgabewerte schön cachen (wenn die Funktion mehrmals aufgerufen wird).

      weis ich aber ich hab jetzt ne bestätigung von profies ;-)

      Wenn es jedoch eine Methode ist, kann solch Cachen auch über ein Attribut der Instanz erfolgen.

      wusste ich nich dankeschön

      vlg MB