Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Konzept Model von MVC

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Konzept Model von MVC

    Hallo

    Ich mache mir Gedanken darüber, wie man vom MVC den Model-Teil programmieren könnte. Dazu sind mir 2 Varianten eingefallen.

    Ausgangsbasis:
    PHP-Code:
    class // beliebige Klasse, dessen Daten in der DB gespeichert werden
    {
       public 
    $x;
       public 
    $y;
       public 
    $z;
       public function 
    __construct($x$y$z)
       {
          
    $this->$x;
          
    $this->$y;
          
    $this->$z;
       }

    Um hier alles möglichst einfach zu halten, werden in keiner Klasse setter/getter verwendet.
    Die properties sind allesamt public.

    Es gibt eine Datenbank:
    PHP-Code:
    class MySql
    {
       public function 
    query($str)
       {
          
    // ...
       
    }

    Und auch noch einen WebService:
    PHP-Code:
    class Web
    {
       public function 
    send($str// hier kann man dem Webserice etwas schicken
       
    {
          
    // ...
       
    }

    In der MySQL-Tabelle A gibt es dann nicht nur die Spalte x, y und z, sondern auch die Spalte id.

    Es soll möglich sein, Daten aus MySql auszulesen und dem Webservice zu schicken.

    Variante 1:

    Hier wird NICHT von A geerbt.
    PHP-Code:
    class ADb
    {
       public 
    $id// fragt man Daten von MySQL ab, erhält man noch eine id
       
    public $a;  // A-Instanz als property
       
    public function select($id)
       {
          
    $db       = new MySql();
          
    $result   $db->query('SELECT x,y,z FROM a WHERE id = '.$id.';');
          
    $this->id $id;
          
    $this->a  = new A($result->x$result->y$result->z);
       }

    PHP-Code:
    class AWeb
    {
       public 
    $uid// fragt man Daten vom Webservice ab, erhält man z. B. noch eine uid
       
    public $a;   // A-Instanz als property
       
    public function send()
       {
          
    $web = new Web();
          
    $web->send($this->a->x.$this->a->y.$this->a->z);
       }

    PHP-Code:
    $aWeb = new AWeb();
    $aDb  = new ADb();
    $aDb->select(1);
    $aWeb->$aDb->a// hier übergibt man eine A-Instanz
    $aWeb->send(); 
    Variante 2:

    Hier WIRD von A geerbt.
    PHP-Code:
    class ADb extends A
    {
       public 
    $id// fragt man Daten von MySQL ab, erhält man noch eine id
       
    public function select($id)
       {
          
    $db       = new MySql();
          
    $result   $db->query('SELECT x,y,z FROM a WHERE id = '.$id.';');
          
    $this->id $id;
          
    $this->x  $result->x;
          
    $this->y  $result->y;
          
    $this->z  $result->z;
       }

    PHP-Code:
    class AWeb extends A
    {
       public 
    $uid// fragt man Daten vom Webservice ab, erhält man z. B. noch eine uid
       
    public function send()
       {
          
    $web = new Web();
          
    $web->send($this->x.$this->y.$this->z);
       }

    PHP-Code:
    $aWeb = new AWeb();
    $aDb  = new ADb();
    $aDb->select(1);
    $aWeb->$aDb->x// hier muss man x, y und z einzeln übergeben
    $aWeb->$aDb->y;
    $aWeb->$aDb->z;
    $aWeb->send(); 
    Vergleich der beiden Varianten:

    Variante 1 hat eine aufwendigere Programmierung von ABd und AWeb, dafür jedoch eine einfache Programmierung im Hauptprogramm. Es muss nur ein A-Objekt übergeben werden.
    Variante 2 hat eine einfachere Programmierung von ABd und AWeb, dafür muss im Hauptprogramm jede Eigenschaft von A einzeln ausgelesen und übergeben werden.

    Mein Favorit wäre Variante 1.

    Was ist eure Meinung dazu?

    P. S. wie bin ich auf das gekommen? Es gab hier mal im Forum von jemanden ein Thema, wo es um MVC ging. Und dort hatte ich so etwas erwähnt: eine Kombination aus Datenbank und Webservice. Darum habe ich mir das hier überlegt. Aber ich bin in OOP noch nicht 100% sattelfest. Deshalb würde mich die Meinung von den Profis interessieren.

  • #2
    Ich würde es noch etwas weiter abstrahieren.
    Ein ServiceLayer, dem man Mapper übergibt, welche wiederum DataAccessObjects erhalten.
    Ein Mapper baut dann ein Model aus DataTransferObjects zusammen, kann aber auch ein Set an Models generieren.
    Damit kommt man recht gut von der "Datenbank-Denke" weg - denn ein z.B. User-Model hat eigentlich nichts mit einer Zeile in der DB zu tun.
    So ganz abschließend hab ich das aber auch noch nie geplant und zwecks Uhrzeit mag ich mir da grad auch keine Gedanken mehr dazu machen.
    Sollte ja aber erstmal als Denkanstoß reichen.
    Noch zwei kleine Tipps: schau dich z.B. bei Matthew Weier O'Phinney um und leg' dir, falls nicht vorhanden, Patterns of Enterprise Application Architecture von Martin Fowler zu.
    VokeIT GmbH & Co. KG - VokeIT-oss @ github

    Kommentar


    • #3
      Habe jetzt im #1 die getter/setter eliminiert. Mir ist klar, dass man das dann im Endeffekt nicht machen sollte. Habe es aber gemacht, damit es übersichtlicher und kürzer wird. Hier geht es nur um das Grundkonzept.

      Kommentar


      • #4
        Ein Denkanstoß bezüglich Variante 2: Google mal nach "favour composition over inheritance" - Vererbung ist keine Allzweckwaffe!
        [IMG]https://g.twimg.com/twitter-bird-16x16.png[/IMG][URL="https://twitter.com/fschmengler"]@fschmengler[/URL] - [IMG]https://i.stack.imgur.com/qh235.png[/IMG][URL="https://stackoverflow.com/users/664108/fschmengler"]@fschmengler[/URL] - [IMG]http://i.imgur.com/ZEqflLv.png[/IMG] [URL="https://github.com/schmengler/"]@schmengler[/URL]
        [URL="http://www.schmengler-se.de/"]PHP Blog[/URL] - [URL="http://www.schmengler-se.de/magento-entwicklung/"]Magento Entwicklung[/URL] - [URL="http://www.css3d.net/"]CSS Ribbon Generator[/URL]

        Kommentar


        • #5
          Ein Model erbt von einer Grundklasse der Models die sich um die Datenbankverbindung etc kümmert. Im Model sind öffentliche Methoden (oder setter/getter bzw öffentliche Eigenschaften im Falle von ORM) durch die Daten abgefragt und gespeichert werden.
          Im Controller (oder wo auch immer) wird ein Objekt des Models angelegt und durch die Methoden Daten geladen und gespeichert. Entweder kann man das Model-Objekt in einer Instanzvariable des Controllers speichern und immer darauf zugreifen (macht z.B. CodeIgniter so):
          PHP-Code:
          $this->user_model->add($_POST); 
          oder man erstellt in diesem Beispiel pro Benutzer ein Objekt (würde ich eher empfehlen):
          PHP-Code:
          $user = new User();
          $user->create_from_array($_POST);
          $user->get_posts($user_id); 
          oder man lehnt sich eben an ein ORM an welches ich selbst sehr gerne nutze:

          PHP-Code:
          $user = new User();
          $user->values($_POST)->save();

          $user = new User($user_id);
          $user->get_posts(); 
          Programming today is a race between developers striving to build better idiot-proof programs, and the universe trying to produce better idiots. So far, the universe is winning.

          Kommentar


          • #6
            Ein Model erbt von einer Grundklasse der Models die sich um die Datenbankverbindung etc kümmert.
            Das gefällt mir aber nicht.

            Eine Frau IST ein Mensch. Ein Mensch IST ein Lebewesen. Hier hat man 2 IST-Beziehungen, d. h. man macht 2 Vererbungen. Frau erbt von Mensch, Mensch erbt von Lebewesen.

            Nach deine Philosophie würde jetzt eine der Klassen von Datenbank erben? Könnte in diesem Falle nur bei Lebewesen sein. Also Lebewesen IST eine Datenbank?

            Das passt nicht.

            Abgesehen davon habe ich in #1 ein Bespiel eingetragen, wo es nicht nur eine DB, sondern auch einen Webservice gibt.

            Lebewesen müsste dann von Datenbank und Webservice erben? Funktioniert nicht. PHP kennt keine Mehrfachvererbung.

            Kommentar


            • #7
              Nein, nein. Die Grundklasse der Models speichert nur ein Objekt der Datenbankklasse in einer Eigenschaft wie z.B. DB. Dies kann über Dependency Injection, Registry, Factory oder was auch immer geschehen. Die Grundklasse ist also nicht die Datenbank sondern kümmert sich nur darum. Vom Model selbst muss sowieso rein gar nichts mehr erben.
              Was der Webservice konkret mit dem Model zu tun hat erschliesst sich mir auch nicht: ist im Grunde genommen doch auch nur eine weitere Klasse welche das Model nutzt (und nicht davon erbt)?

              Also eher Klasse X nutzt Model X, Model X ist ein Model, Model nutzt Datenbank.
              Programming today is a race between developers striving to build better idiot-proof programs, and the universe trying to produce better idiots. So far, the universe is winning.

              Kommentar


              • #8
                Dann probier mal nach dieser Philosophie folgendes zu machen: Du liest Daten aus der DB und verschickst sie an den Webservice. Also wie in #1. Ich glaube nicht, dass das nach deiner Philosophie möglich ist. Zumindest kann ich mir so eine Programmierung nicht vorstellen.

                Also von Tabelle a die Daten in eine A-Instanz und dann die Daten an den Webservice verschicken.

                Kommentar


                • #9
                  Zitat von bitsnack Beitrag anzeigen
                  Also eher Klasse X nutzt Model X, Model X ist ein Model, Model nutzt Datenbank.
                  Und genau da liegt der Fehler.
                  Ein Model weiß nichtmal, was eine Datenbank ist, geschweige denn, wie man eine benutzt.
                  Darum kümmert sich ein spezialisierter Mapper, wovon es auch gerne mehrere geben kann, z.B. einer, der mit Webservices arbeiten kann, einer für DBs, einer für Flatfiles etc.
                  Sehr interessant ist dieser Webcast: http://www.slideshare.net/weierophin...bjects-1766001
                  VokeIT GmbH & Co. KG - VokeIT-oss @ github

                  Kommentar


                  • #10
                    Em bitte?

                    PHP-Code:
                    $data = new Data_Model($data_id);
                    $this->send($data->get_data()); 
                    Habe das Gefühl dass wir völlig aneinander vorbeireden.

                    Zitat von G.Schuster Beitrag anzeigen
                    Und genau da liegt der Fehler.
                    Ein Model weiß nichtmal, was eine Datenbank ist, geschweige denn, wie man eine benutzt.
                    Darum kümmert sich ein spezialisierter Mapper, wovon es auch gerne mehrere geben kann, z.B. einer, der mit Webservices arbeiten kann, einer für DBs, einer für Flatfiles etc.
                    Sehr interessant ist dieser Webcast: http://www.slideshare.net/weierophin...bjects-1766001
                    Mit der Datenbank meinte ich eben ein Objekt irgendeiner für den Datenspeicher zuständigen Klasse.
                    In Models wie es sie in CodeIgniter gibt nutzen die Methoden der Models einfach direkt das Datenbankobjekt (z.B. einen QueryBuilder). Alternativ können die Methoden auch nur die Eigenschaften des Models bearbeiten welche dann wieder von der Grundklasse gespeichert werden.
                    Programming today is a race between developers striving to build better idiot-proof programs, and the universe trying to produce better idiots. So far, the universe is winning.

                    Kommentar


                    • #11
                      Ein Model weiß nichtmal, was eine Datenbank ist
                      Der Meinung bin ich auch.
                      Gefällt mir. Also wie ich es auch in #1 gemacht habe
                      Ich glaube, ich bleibe bei der Variante 1.
                      Mit der Datenbank meinte ich eben ein Objekt irgendeiner für den Datenspeicher zuständigen Klasse.
                      Ich glaube, du meinst die Philosophie, die auch bei Propel zum Einsatz kommt. Ersetze bei meinem Beispiel mit Frau, Mensch, Lebewesen, das Datenbank einfach durch einen anderen Begriff. Ist wie bei Propel, würde ich sagen.

                      Kommentar


                      • #12
                        Also irgendwie habe ich das Thema des Threads nicht wirklich verstanden und bin mittlerweile ziemlich verwirrt. Entweder wir reden wirklich nur komplett aneinander vorbei und keiner versteht den jeweils anderen oder ich bin schlichtweg zu doof was ich eher befürchte. Nun ist das aber ein Forum und ich bin hauptsächlich hier um etwas zu lernen: Wäre jemand so freundlich und könnte mir das mal ganz langsam erklären?
                        Programming today is a race between developers striving to build better idiot-proof programs, and the universe trying to produce better idiots. So far, the universe is winning.

                        Kommentar


                        • #13
                          Schau dir den Webcast an und lies' den Blog von Matthew dann wirst du auch verstehen.
                          Kurz gesagt: ein Model darf niemals irgendwas über eventuelle Speichermethoden wissen, also auch nicht in irgendwlechen Properties eine DB-Verbindung vorhalten.
                          Damit zerstörst du dir jede Möglichkeit, von DB-Speicherung auf z.B. FlatFiles umzustellen, ohne alle Models händisch bearbeiten zu müssen.
                          VokeIT GmbH & Co. KG - VokeIT-oss @ github

                          Kommentar


                          • #14
                            Worum geht es bei OOP? Darum, die Welt in einer vereinfachten Form abzubilden.

                            Angenommen, man möchte ein Haus objektorientiert nachbilden. Es hat eine gewisse Höhe, Breite und Tiefe. Es gibt Türen und Fenster. In den Räumen gibt es Möbelstücke, z. B. Stühle und Tische. Und in manchen Arbeitszimmern stehen auch Drehstühle.

                            Bleiben wir jetzt mal bei diesen Stühlen. Es gibt also einige Drehstühle. Ein Drehstuhl ist - wie schon erwähnt - ein Stuhl. Und ein Stuhl ist ein Möbelstück.

                            Jetzt bilden wir das objektorientiert nach:

                            Möbelstück <|--- Stuhl <|--- Drehstuhl

                            Et voila. Schon haben wir die Welt in einer vereinfachten Form abgebildet.

                            Das Möbelstück erbt NICHT von einer Datenbank, oder sonst etwas, was irgendwelche Infos von einer Datenbank bezieht.

                            Kommentar


                            • #15
                              Zitat von G.Schuster Beitrag anzeigen
                              Schau dir den Webcast an und lies' den Blog von Matthew dann wirst du auch verstehen.
                              Kurz gesagt: ein Model darf niemals irgendwas über eventuelle Speichermethoden wissen, also auch nicht in irgendwlechen Properties eine DB-Verbindung vorhalten.
                              Damit zerstörst du dir jede Möglichkeit, von DB-Speicherung auf z.B. FlatFiles umzustellen, ohne alle Models händisch bearbeiten zu müssen.
                              Wenn ich mal etwas fragen darf bevor ich mir die Ressourcen angesehen habe: Wenn ein Model welches im Endeffekt Daten abfragen und zurückgeben und auch wieder speichern soll, aber keine Ahnung von irgendeiner Methode zur Datenabfrage oder Speicherung hat, wie will es dann seine Aufgabe erledigen?
                              Programming today is a race between developers striving to build better idiot-proof programs, and the universe trying to produce better idiots. So far, the universe is winning.

                              Kommentar

                              Lädt...
                              X