Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Statische Methoden oder Instanzmethoden in Framework

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Statische Methoden oder Instanzmethoden in Framework

    Moin,

    ich stehe bei dem Framework, welches ich programmieren will, vor der Frage, ob ich bei den meisten Klassen statische Methoden oder Instanzmethoden verwenden soll.

    Meine momentane Meinung ist, dass Instanzmethoden nur dann wirklich Sinn machen, wenn man auch mehrere Instanzen von etwas haben könnte, also z.B. "User" oder "Post".

    Es werden immer nur abgeleitete Klassen verwendet, damit man diese für das jeweilige Projekt anpassen kann.

    Beispiel:
    Sehr häufig verwende ich die Klasse "Error", welche eine Fehlermeldung anzeigt. Da das Skript bei einem Fehler abgebrochen wird und man so nicht mehrere Fehler gleichzeitig haben kann, macht also eine statische Methode mehr Sinn, weil man nicht extra eine Instanz braucht. Dafür würde ich aufrufen \Error::error(); Die Error-Klasse ist von \Base\Error abgeleitet und selber leer. Der Nachteil daran ist, dass man theoretisch noch immer \Base\Error::error() aufrufen kann, was man ja eigentlich nicht soll und das evtl. nicht ganz so professionell ist.
    Wenn ich das als Instanzmethode machen will, müsste ich ganz am Anfang von der Error-Klasse eine Instanz erzeugen, diese in einer Klasse "ServiceManager" speichern und dann bei einem Fehler immer $serviceManager->get('error')->error(); aufrufen. Das hat wiederum den Nachteil, dass man mehr tippen muss und der String 'error' keine Autovervollständigung hat.

    Also haben beide Wege ihre Nachteile. Was soll ich tun?


  • #2
    Also statics sowieso nicht.

    Machs doch wie bei Laravel und nutze __callStatic (http://php.net/manual/de/language.oop5.overloading.php)

    LG
    https://github.com/Ma27
    Javascript Logic is funny:
    [] + [] => "", [] + {} => object, {} + [] => 0, {} + {} => NaN

    Kommentar


    • #3
      Nein, mach es bitte nicht wie Laravel, verwende möglichst keine statischen Methoden. Das ist so oft Zweckentfremdung.

      Das man immer noch deine Base-Klasse aufrufen kann ist "üblich". Das kann man bei Laravel, bei Symfony, bei Silex, bei was-weis-ich. Das nennt sich jedoch Code-Style. Und wenn sich ein Entwickler nicht daran hält, ist das sein Problem.

      So nebenbei, es gibt das DRY-Prinzip. Solch eine Fehlermeldung solltest du über eine Exception realisieren, die von einem Core-Controller/Kernel gefangen wird. Das Anzeigen von Fehlermeldungen hat in einem Controller nichts zu suchen.
      GitHub.com - ChrisAndChris - RowMapper und QueryBuilder für MySQL-Datenbanken

      Kommentar


      • #4
        Der Nachteil daran ist, dass man theoretisch noch immer \Base\Error::error() aufrufen kann, was man ja eigentlich nicht soll und das evtl. nicht ganz so professionell ist.
        Ich halte das nicht für ein relevantes Problem. Nicht böse gemeint, aber statt dir über dieses Problem den Kopf zu zerbrechen, nutze deine Zeit lieber zu mehr Eigenrecherche bezüglich des Threadthemas.

        Markiere die Basisklassen einfach als abstract, damit ist für Nutzer des Frameworks gesagt, dass diese Klassen nur als Basis für abgeleitete Klassen dienen. Zwar lassen sich dann statische Methoden immer noch aufrufen, aber das ist dann einfach nicht mehr dein Problem.

        Kommentar


        • #5
          Zitat von ChristianK Beitrag anzeigen
          verwende möglichst keine statischen Methoden.
          Also keine statischen Methoden, sondern am Anfang von "jedem Mist" eine Instanz erzeugen, in einer Klasse speichern und dann immer über die Klasse aufrufen. Gibt es auch eine Begründung warum nicht static?

          Zitat von ChristianK Beitrag anzeigen
          So nebenbei, es gibt das DRY-Prinzip. Solch eine Fehlermeldung solltest du über eine Exception realisieren, die von einem Core-Controller/Kernel gefangen wird. Das Anzeigen von Fehlermeldungen hat in einem Controller nichts zu suchen.
          Im Prinzip wirft die "error"-Methode auch nur eine Exception.

          Kommentar


          • #6
            Ja, du kannst das auch so interpretieren. Oder die andere Variante wäre, die Instanz genau dann zu erzeugen, wann sie benötigt wird.

            Und wenn das "im Prinzip" so ist, wieso wirfst du die Exception nicht gleich direkt?
            GitHub.com - ChrisAndChris - RowMapper und QueryBuilder für MySQL-Datenbanken

            Kommentar


            • #7
              Zitat von xxluke Beitrag anzeigen
              Also keine statischen Methoden, sondern am Anfang von "jedem Mist" eine Instanz erzeugen, in einer Klasse speichern und dann immer über die Klasse aufrufen. Gibt es auch eine Begründung warum nicht static?
              Keine, die es verbieten würde, wenn du es richtig machst. Ich finde die Idee der "static facades" von Laravel beim Schreiben von Code sehr angenehm. Kurz gesagt wird eine Instanz erzeugt, diese aber versteckt. Z. B. wird zunächst eine Instanz von Namespace\Log erzeugt und gespeichert. Zum Zugriff auf Methoden nutzt man nun aber eine Klasse Namespace\Facades\Log und statische Methoden. Die facade-Klasse bietet diese Methoden gar nicht an. Wird aber einer dieser nicht vorhandenen Methoden aufgerufen, fängt die Klasse das ab und ruft statt dessen die Methode der erzeugten Instanz von Namespace\Log auf.

              Stark vereinfachtes Beispiel:
              PHP-Code:
              <?php namespace Namespace/Facades/Log  // (Die Website mag keine Namensraueme mit Backslash :P)

              class Log {
                  public static function 
              __callStatic($method$args)
                  {
                      
              $instance = static::getFacadeInstance(); // Irgendwoher die Instanz bekommen - das kann man natuerlich verschieden implementieren
                  
                      
              return $instance->$method(); // (Argumente hier nicht beruecksichtigt!)
                  
              }
              }

              // Zugriff nach  Zuweisung der Instanz etc.:
              Log::exampleMethod();

              Kommentar


              • #8
                Trotz allem verstehe ich nicht, was für einen Sinn diese Spielerei mit statischen Methoden hat? Saubere Programmierung kann da wohl kein Argument mehr sein.
                GitHub.com - ChrisAndChris - RowMapper und QueryBuilder für MySQL-Datenbanken

                Kommentar


                • #9
                  Also keine statischen Methoden, sondern am Anfang von "jedem Mist" eine Instanz erzeugen, in einer Klasse speichern und dann immer über die Klasse aufrufen. Gibt es auch eine Begründung warum nicht static?
                  Richtig. Von jedem Mist. Denn wenn ich morgen bspw. entscheide, dass ich ein Fehlerobjekt vor der Ausführung noch durch einen Logger schicken will, oder meine View durch einen Testprozess oder meinen Controller wiederverwenden und dynamisch erzeugen oder meine Datenbank dynamisch erzeugen oder zwei verschiedene Datenbanken in einer Anwendung benutzen oder oder oder, dann steh ich mit statics einfach mal da. Davon mal ab, dass Statics für Autoloader nix taugen, im Factory Pattern nichts taugen, im Decorator Pattern nicht anwendbar sind...

                  Wer aus Bequemlichkeit static verwendet, kann auch gleich bei Funktionen bleiben. Meine Meinung.
                  --

                  „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


                  • #10
                    Zitat von ChristianK Beitrag anzeigen
                    Trotz allem verstehe ich nicht, was für einen Sinn diese Spielerei mit statischen Methoden hat?
                    Für mich: Convenience.

                    Bei Laravel wird übrigens niemand dazu gezwungen, selbstverständlich kann man auf die Instanzen zugreifen.

                    Kommentar


                    • #11
                      Und Laravel-Facades instanziieren nicht selbst on-use sondern holen ihre Instanz am DI-Container ab. Was generell nicht verkehrt ist, auch wenns dazu verleitet neben der Spur zu arbeiten.
                      [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


                      • #12
                        Diese laravel static facades sollte man ebenfalls nicht benutzen. Im Idealfall wird alles via DependencyInjection verdrahtet.
                        Autowiring ist hier der neue heiße Scheiß. Schau dir mal PHP-DI4 an (kann laravel übrigens auch). Da kann man auch auf Lazy-Instantiation durch ProxyObjects zurückgreifen. Kann man aber auch manuell über Factories oder Services abbilden, wenn man will.

                        Am Besten alles was static ist als Designfehler betrachten und baldmöglichst fixen, dann ist man auf der sicheren Seite.
                        Standards - Best Practices - AwesomePHP - Guideline für WebApps

                        Kommentar


                        • #13
                          autowiring ist kein wirklich generell etablierter Begriff, oder? Jedenfalls wird das im Rahmen von L5 kaum so betitelt.

                          Im Idealfall wird alles via DependencyInjection verdrahtet.
                          Passiert bei den static facades ja - über service container - oder meinst du das anders?

                          Autowiring ist hier der neue heiße Scheiß. (...) Am Besten alles was static ist als Designfehler betrachten
                          Liest sich, dass wenn du das so sagst, nicht wie der Weg der Vernunft sondern des vorschnellen Urteils. Klingt nach "es ist neu, es löst ein Problem, es muss besser sein". Deine Ausdrucksweise ist jedenfalls klar so intoniert. Was ist mit den downsides? Soll nicht heißen, dass ich das Prinzip schlecht reden will. Aber zum Beispiel, wenn ich in einer Methode ein halbes dutzend Klassen verwende, muss ich dann ein halbes dutzend Parameter zur Methode hinzufügen? Dürfte ja auch nicht per IDE automatisierbar sein, außer irgend ein guessing nach dem Motto "Zugriff auf nicht instanziierte Variable $view? Bau ich mal auf Verdacht View $view als Parameter ein" - oder?
                          Naja hab mich damit noch nicht groß auseinandergesetzt. Ist halt uncool wenn Laravel erst facades als das Ding verkauft und dann auf einmal einen anderen Weg als "den" Weg verkauft. Da komme ich gar nicht umhin skeptisch zu sein - wie lang hält sich das dann, bis entschieden wird, dass das jetzt nicht mehr tauge und Konzept GiveMeAName die neue Norm wird?

                          Kommentar


                          • #14
                            Mit heißer Scheiß bezieht er sich eher auf die "all everywhere"-Natur von Static facades. Laravel verhindert halt nicht das du mit den Templates in Models kuschelst, weil es die Einsatzmöglichkeiten nicht abgrenzen kann.
                            [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
                              Ok. Ich bezog mich allerdings auf die druckvolle Artikulation.

                              Aber interessant: D. h. zu autowiring gehört auch, dass man bei der DI festlegen kann, was injiziert werden kann und was nicht?

                              Kommentar

                              Lädt...
                              X