MB: Klassen in Modeln oder Repositories aufbauen?

moin,

Sollte man Klassen (z.B. Gästebuch Einträge, Kontakte) lieber in Modeln oder Respositories konstruieren und dann weiter verarbeiten lassen?

Datensätze von der Database zu fetchen und im Repository als array zu verarbeiten und zu übergeben, schein mir sinnvoller zu sein. Das Model, welches auf das Repository zugreift, kann dann dieses array in eine Klasse umwandeln.

Oder sollte man diese Konstruktion der Klassen von der Konvention her im Repository vollziehen? Mir schein das chaotischer.

Mir ist bewusst das man mit PDO Klassen aus der Database fetchen kann. Aber eine Klasse die ein array als property, neben z.B. strings, beinhaltet, ist PDO überfordert. Siehe: Kann man mit PDO Klassen-Arrays aus der Database fetchen

lgmb

  1. moin,

    Datensätze von der Database zu fetchen und im Repository als array zu verarbeiten und zu übergeben, schein mir sinnvoller zu sein. Das Model, welches auf das Repository zugreift, kann dann dieses array in eine Klasse umwandeln.

    Array in eine Klasse umwandeln? Was soll das sein, was soll das werden?

    Ein Array an eine Klasse binden, das geht schon eher und das geht auch in PHP. Über die Bindung können Methoden aufgerufen werden, z.B. um das Array in eine DB oder Datei zurückzuschreiben (Persistierung).

    Oder mit dem Array wird eine Instanz einer Klasse erstellt. So werden die Methoden direkt über die Instanz aufgrufen.

    Oder sollte man diese Konstruktion der Klassen von der Konvention her im Repository vollziehen? Mir schein das chaotischer.

    Bahnhof.

    MfG

    1. moin,

      Datensätze von der Database zu fetchen und im Repository als array zu verarbeiten und zu übergeben, schein mir sinnvoller zu sein. Das Model, welches auf das Repository zugreift, kann dann dieses array in eine Klasse umwandeln.

      Array in eine Klasse umwandeln? Was soll das sein, was soll das werden?

      primitive Daten aus einer Tabelle in der Datenbank einheitlich als eine zu behandeln…

      new Kontakt(
        $records[ $i ][ 'vorname' ],
        $records[ $i ][ 'nachname ],
        $records[ $i ][ 'email' ],
        $records[ $i ][ 'betreff' ],
        $records[ $i ][ 'nachricht' ]
      );
      

      und vielle davon zusammenfassend als array

      return [
        new Kontakt( /* ... */ ),
        new Kontakt( /* ... */ ),
        new Kontakt( /* ... */ ),
        ...,
      ];
      

      …als eben viele zu vertarbeiten $vorname, $nachname, $email, $betreff, $nachricht

      lgmb

      1. Hallo MB,

        new Kontakt(
          $records[ $i ][ 'vorname' ],
          $records[ $i ][ 'nachname ],
          $records[ $i ][ 'email' ],
          $records[ $i ][ 'betreff' ],
          $records[ $i ][ 'nachricht' ]
        );
        

        Manchmal sind Syntaxhighlighter kaputt, manchmal aber auch nicht.

        Bis demnächst
        Matthias

        --
        Rosen sind rot.
        1. moin,

          Hallo MB,

          new Kontakt(
            $records[ $i ][ 'vorname' ],
            $records[ $i ][ 'nachname ],
            $records[ $i ][ 'email' ],
            $records[ $i ][ 'betreff' ],
            $records[ $i ][ 'nachricht' ]
          );
          

          Manchmal sind Syntaxhighlighter kaputt, manchmal aber auch nicht.

          habs gesehen danke für den Hinweis 😉.

          lgmb

      2. moin,

        Datensätze von der Database zu fetchen und im Repository als array zu verarbeiten und zu übergeben, schein mir sinnvoller zu sein. Das Model, welches auf das Repository zugreift, kann dann dieses array in eine Klasse umwandeln.

        Array in eine Klasse umwandeln? Was soll das sein, was soll das werden?

        primitive Daten aus einer Tabelle in der Datenbank einheitlich als eine zu behandeln…

        Ja, natürlich. Du möchtest also eine Instanz erstellen und nicht die Klasse. Die Klasse muss nämlich vorher schon da sein.

        Ansonsten ist das eine durchaus zweckmäßige Vorgehensweise. Vor allem hinsichtlich der Datenhaltung über austauschbare Layer: $user = new User( file => 'users' ) oder $user = new User( database => 'users' ) würde beispielsweise eine Userinstanz erstellen.

        Austauschbar ist der Persistierungslayer (Datenbank // Datei) die Methode $user->update() hingegen ist immer dieselbe.

        MfG

        1. moin,

          moin,

          Datensätze von der Database zu fetchen und im Repository als array zu verarbeiten und zu übergeben, schein mir sinnvoller zu sein. Das Model, welches auf das Repository zugreift, kann dann dieses array in eine Klasse umwandeln.

          Array in eine Klasse umwandeln? Was soll das sein, was soll das werden?

          primitive Daten aus einer Tabelle in der Datenbank einheitlich als eine zu behandeln…

          Ja, natürlich. Du möchtest also eine Instanz erstellen und nicht die Klasse. Die Klasse muss nämlich vorher schon da sein.

          sry, tut mir leid. Ja meine ich.

          lgmb

          1. moin,

            Ja, natürlich. Du möchtest also eine Instanz erstellen und nicht die Klasse. Die Klasse muss nämlich vorher schon da sein.

            sry, tut mir leid. Ja meine ich.

            Sehr schön. Und die Sache mit der Persistierung hast Du auch verstanden? Genau das beantwortet nämlich Deine Frage. D.h., ein Repository ist unabhängig davon, wo die Daten physikalisch liegen. Es kann in einer DB abgelegt sein, muss aber nicht. Dein Datenmodell kann genausogut aus einem Repository heraus erstellt werden welches die Daten in Dateien speichert. Und natürlich auch wieder dorthin zurückgeschrieben werden.

            MfG

            1. moin,

              wenn ich z.B. ein Gästebuch habe und die Daten aus der DB kommen, dann brauch ich doch nurt daten reinschreiben und / oder rausholen. Ebenso ist es mit Konktakt einträgen. Persistenz brauchrt man denke ich z.B. Chats. Aber ich hab damit noch nicht gearbeitet sry und kann nur vermurtungen anstellen. Allerdings möchte ich gern "Zukünftig" damit arbeiten aber nicht jetzt.

              [...] ein Repository ist unabhängig davon, wo die Daten physikalisch liegen.

              ist mir bewusst dank euch 😉.

              Dein Datenmodell kann genausogut aus einem Repository heraus erstellt werden welches die Daten in Dateien speichert. Und natürlich auch wieder dorthin zurückgeschrieben werden.

              jepp. Meine Ausgangsfrage "Ob es sinnvoll ist", wurde mir von @@RolfB und Dir beantwortet

              lgmb

      3. moin,

        verdammt! Ich hab das Hochkomma nach nachname im assoziativem Array $records[ $i ][ 'nachname ] vergessen 😟. Sorry!!! Jetzt bleibt mein Fehler im Code für immer bestehen.

        lgmb

      4. moin,

        Datensätze von der Database zu fetchen und im Repository als array zu verarbeiten und zu übergeben, schein mir sinnvoller zu sein. Das Model, welches auf das Repository zugreift, kann dann dieses array in eine Klasse umwandeln.

        Array in eine Klasse umwandeln? Was soll das sein, was soll das werden?

        primitive Daten aus einer Tabelle in der Datenbank einheitlich als eine zu behandeln…

        new Kontakt(
          $records[ $i ][ 'vorname' ],
          $records[ $i ][ 'nachname ],
          $records[ $i ][ 'email' ],
          $records[ $i ][ 'betreff' ],
          $records[ $i ][ 'nachricht' ]
        );
        

        und vielle davon zusammenfassend als array

        In Perl würden wir sagen das wäre ein Hash of Hashes. Man kann aber auch sagen, hier würde das Entity/Attribute/Value Modell passen. Das kann man recht gut in MySQL umsetzen als eine Tabelle mit 3 Feldern. D.h., wenn neue Eigenschaften zu einer Entity hinzukommen, muss da das DB Design nicht geändert werden. Überlege Dir welches Feld einen Index bekommt damit das performant abgefragt werden kann.

        MfG

        1. Tach!

          In Perl würden wir sagen das wäre ein Hash of Hashes. Man kann aber auch sagen, hier würde das Entity/Attribute/Value Modell passen.

          EAV kann man prinzipiell überall drüberstülpen. Der Preis für EAV ist aber, dass man eine flexible Struktur braucht, um die unbegrenzte Anzahl von Attributen/Eigenschaften mit zur Entwicklungszeit unbekannten Namen abbilden zu können. Das braucht man nur selten. Meist reicht es, die Eigenschaften konkret festzulegen. Aus dem Beispiel war auch nicht ersichtlich, dass das benötigt wird. Stattdessen waren Eigenschaften mit bekannten Namen zu sehen. Das geht ganz wunderbar ohne den EAV-Overhead.

          dedlfix.

          1. Der Overhead ist gering. Ich hatte schon EAV Tabellen mit 300tausend Einträgen, die Abfragen liegen im ms Bereich. Allerdings neigen solche Tabellen zur Vermüllung. MfG

            1. Tach!

              Der Overhead ist gering.

              Vielleicht wenn man es mit einer konkreten Anzahl von Eigenschaften verwendet. Dann braucht man aber kein EAV. Eine variable Anzahl unbekannter Eigenschaften muss man irgendwie in der Benutzeroberfläche handhaben, inklusive eines administrativen Teils zu ihrer Verwaltung. Als gering würde ich das nicht bezeichnen.

              dedlfix.

              1. Tach!

                Der Overhead ist gering.

                Vielleicht wenn man es mit einer konkreten Anzahl von Eigenschaften verwendet. Dann braucht man aber kein EAV. Eine variable Anzahl unbekannter Eigenschaften muss man irgendwie in der Benutzeroberfläche handhaben, inklusive eines administrativen Teils zu ihrer Verwaltung. Als gering würde ich das nicht bezeichnen.

                Warum sollte das ein Problem sein oder gar zu einem Overhead führen? In einer Benutzeroberfläche weitere Felder hinzuzufügen damit weitere Eigenschaften erfasst werden können? Das geht per JS mit einem Klick! Oder entsprechend der Attribute/Werte Paare einen Eintrag mit allen Attributen im Benutzerbackend darzustellen? Wo siehst Du da ein Problem?

                Ein DB-Design zu ändern ist da deutlich aufwendiger, als nur das Backend anzupassen. Und warum sollte eine Anwendung überhaupt vom DB Design abhängig sein? Das ist ziemlich konservativ.

                MfG

                1. Hallo pl,

                  eine Anwendung ist nie vom DB-Design abhängig, sondern das DB-Design von den beabsichtigten Anwendungen. Kriterien sind Einfachheit der Zugriffe, Performance, Erweiterbarkeit, Konsistenz.

                  Man kann ein System wie MySQL als EAV-Speicher nutzen. Aber dann kannst Du auf MYSQL auch verzichten und pro E eine Datei schreiben, wo die AV drin sind.

                  Rolf

                  --
                  sumpsi - posui - clusi
                  1. hi @Rolf B

                    eine Anwendung ist nie vom DB-Design abhängig, sondern das DB-Design von den beabsichtigten Anwendungen. Kriterien sind Einfachheit der Zugriffe, Performance, Erweiterbarkeit, Konsistenz.

                    Mein Trend geht in Richtung Abstraktion und austauschbare Layer. Natürlich bestimmt die Anwendung die Datenstruktur und wie die Daten für den wahlfreien Zugriff im Hauptspeicher adressiert werden.

                    Man kann ein System wie MySQL als EAV-Speicher nutzen. Aber dann kannst Du auf MYSQL auch verzichten und pro E eine Datei schreiben, wo die AV drin sind.

                    Wie gesagt, austauschbare Layer sind der Trend. Der Anwendung ist es egal, ob die Daten in MySQL oder in einer Datei ihre Persistierung finden, das ist Sache der Konfiguration.

                    MfG

                    1. Hallo pl,

                      Wie gesagt, austauschbare Layer sind der Trend.

                      Du hast säuberlich das Wesentliche vom Unwesentlichen getrennt und das Wesentliche ignoriert.

                      Abstraktion und austauschbare Layer sind nicht nur Dein Trend, sondern generell der Trend in der Informatik, darüber müssen wir nicht diskutieren.

                      Meine Kritik an EAV in einer SQL-DB ist, dass die den Daten innewohnende Struktur sich nicht in der Struktur der Persistenzschicht wiederfindet. Diese Struktur wird beim Speichern ist eine Liste von E-A-V Tupeln aufgelöst und muss beim Laden wiederhergestellt werden.

                      Du verzichtest damit auf den Vorteil, den Dir die strukturierte Datenhaltung in einer relationalen DB bietet, und nutzt das Potenzial des DBMS nur zu einem winzigen Teil.

                      In einer Single-User oder Read-Only Umgebung ist das egal. In einem belasteten Multiuser-System brichst Du damit zusammen, weil Du Features wie Record Locking nicht nutzen kannst. Das Speichern eines einzigen Objekts verlangt, dass Du pro Attribut eine Row updaten musst. Statt eines einzelnen Satzes musst Du mehrere Sätze locken, das ist viel mehr Overhead. Strategien wie Optimistisches Sperren sind damit nicht realisierbar.

                      Rolf

                      --
                      sumpsi - posui - clusi
                      1. hi @Rolf B

                        Meine Kritik an EAV in einer SQL-DB ist, dass die den Daten innewohnende Struktur sich nicht in der Struktur der Persistenzschicht wiederfindet. Diese Struktur wird beim Speichern ist eine Liste von E-A-V Tupeln aufgelöst und muss beim Laden wiederhergestellt werden.

                        Das ist beim Serialisieren in eine Datei ganz genauso. Auch hier gibt es Tupel und den Feldbegriff.

                        Abstraktion und austauschbare Layer sind nicht nur Dein Trend, sondern generell der Trend in der Informatik, darüber müssen wir nicht diskutieren.

                        Und warum kommst Du mir da jetzt mit Record-Locking?

                        MfG

                        1. Hallo pl,

                          Deshalb.

                          Rolf

                          --
                          sumpsi - posui - clusi
                      2. hi @Rolf B

                        Abstraktion und austauschbare Layer sind nicht nur Dein Trend, sondern generell der Trend in der Informatik, darüber müssen wir nicht diskutieren.

                        Meine Kritik an EAV in einer SQL-DB ist, dass die den Daten innewohnende Struktur sich nicht in der Struktur der Persistenzschicht wiederfindet. Diese Struktur wird beim Speichern ist eine Liste von E-A-V Tupeln aufgelöst und muss beim Laden wiederhergestellt werden.

                        Du verzichtest damit auf den Vorteil, den Dir die strukturierte Datenhaltung in einer relationalen DB bietet, und nutzt das Potenzial des DBMS nur zu einem winzigen Teil.

                        Erkennst Du den Widerspruch? Also entweder reden wir über austauschbare Layer oder über Potenziale die ein DBMS hat.

                        MfG

  2. Hallo MB,

    wenn ich Dich richtig verstehe, hast Du eine 1:n Beziehung in der DB und möchtest die Rows auf der "N" Seite dem Objekt, das aus der "1" Seite entsteht, als Array-Attribut anhängen.

    Sowas ist schon im Sinne eines Repositories. Das ist eine Klasse, die "Domänenspezifische Sichten" erzeugt (Domäne hier im Sinne eines fachlichen Datenbereichs) und sie als Modell (also Objekt-Graph) ausspuckt. Das Repository kann handgemacht sein oder durch eine ORM Library bereitgestellt werden.

    Die Weiterverarbeitung des Modells übernimmt dann eine Controller Klasse. Ob man Fachlogik im Modell unterbringt oder nicht, da scheiden sich teils die Geister. Ich sehe das so, dass das vom Repository gelieferte Modell möglichst "dumm" sein muss, ein Netz aus PO*Os (plain old * object, je nach Sprache ein POJO, POCO oder POPO).

    Ob Du deine fachliche Verarbeitung oder deine Ausgabe dann basierend auf dem gelesenen Modell erzeugst oder es zuerst in ein Viewmodell überführst, hängt von der Aufgabenstellung ab.

    Rolf

    --
    sumpsi - posui - clusi
    1. moin,

      schön erklärt. Dankeschön! Neben bei bemerkt: Ich arbeite unter einer SQL-Tabelle die Atomar ist also NF1. Ich bin zu doof für praktische NF2, NF3 Tabllen. Aber theoritisch kann ichs bringt mir aber nix.

      lgmb

      1. Hallo MB,

        d.h. du hast ein n-fach Attribut in einer Zeile gespeichert?

        Deine Sache - aber das musst Du von Hand in ein Array übersetzen. PDO hilft Dir dann Null Komma Garnix.

        Rolf

        --
        sumpsi - posui - clusi
        1. moin,

          Deine Sache - aber das musst Du von Hand in ein Array übersetzen. PDO hilft Dir dann Null Komma Garnix.

          I know 😕

          lgmb

      2. Moin,

        NF1? Der Begriff der Normalform ist bei einem ORM unsinnig.

        MfG

        1. moin,

          NF1? Der Begriff der Normalform ist bei einem ORM unsinnig.

          das verstehe ich nicht? Erklär bitte.

          lgmb

          1. moin,

            NF1? Der Begriff der Normalform ist bei einem ORM unsinnig.

            das verstehe ich nicht? Erklär bitte.

            Das Konzept einer relationalen Datenhaltung ist anders als das Konzept einer objektorientierten Datenhaltung. ORM vermittelt da nur und macht das Konzept der relationalen Datenhaltung für die Anwendung transparent, d.h., in der Anwendung gibt es keine Normalform.

            MfG

            1. moin,

              Das Konzept einer relationalen Datenhaltung ist anders als das Konzept einer objektorientierten Datenhaltung. ORM vermittelt da nur und macht das Konzept der relationalen Datenhaltung für die Anwendung transparent, d.h., in der Anwendung gibt es keine Normalform.

              ah ok verstehe. Jetzt weris ich was du meinst. SQL-Tabellen die eine Reduntanz z.B. …

              Seite A: Artikel A;
              Seite A: Artikel B;
              Seite A: Artikel C
              

              …vorbeugen wie etwa…

              Seite A : [
                Artikel A,
                Artikel B,
                Artikel C
              ]
              

              wie man sieht sind da zwei SQL-Tabellen drin. Es geht natürlich auch anders wie du ansprachst in ORM jedoch möchte ich ja lernen.

              lgmb

              P.S.: Ich wollte dir nur an einem trivialen Beispiel demonstrieren, damit Missverständnissen garnicht erst aufkommen 😉.

              1. Moin,

                willst Du Dich mal selbst an einem ORM versuchen? Natürlich könntest Du eine relationale Tabelle aufsetzen mit der oid (Objekt id) als Primärschlüssel und für jede Eigenschaft ein Feld:

                oid|name|vname|plz|ort

                Jedes Objekt wäre ein eigener Record mit einer eindeutigen id (primary key). Dennoch sind da jede Menge Redundanzen möglich, aus OO Sicht also identische Objekte:

                1|Haar|Franz|12345|Zopftn 2|Haar|Franz|12345|Zopftn

                Bedenke auch, daß ein Hinzufügen weiterer Eigenschaften eine Änderung des DB Designs erfordert. Eine 3 spaltige Tabelle vermeidet diesen Umstand:

                oid|eingeschaft|wert

                wobei jede Eigenschaft einen eigenen Record benötigt:

                1|name|Haar 1|vname|Franz 1|plz|12345 1|ort|Zopftn

                aber das Hinzufügen weiterer Eigneschaften wenigstens kein DB ReDesign mehr erfordert. Ein bestimmtes Objekt sieht dann so aus:

                Person = {
                   name:  Haar,
                   vname: Franz,
                   plz:   12345,
                   ort:   Zopftn
                }
                

                der besseren Lesbarkeit wegen mal nicht gequotet. Und siehe da, wo das herkommt, ist der Anwendung völlig Wurst. Genausowenig wie es eine Rolle spielen würde ob die Tabellen der Normalform entsprechen oder nicht. Natürlich kannst Du auch mehrere Objekte da rausholen:

                Personen = {
                 1: {
                   name:  Haar,
                   vname: Franz,
                   plz:   12345,
                   ort:   Zopftn
                 },
                 2: {
                   name:  Haar,
                   vname: Franz,
                   plz:   12345,
                   ort:   Zopftn
                }
                

                MfG

        2. Hallo pl,

          sorry - aber das ist wohl Blödsinn. ORM funktioniert auf einer normalisierten DB deutlich besser als auf einer denormalisierten DB. Zumindest, wenn es um Updates geht. Bei rein lesenden Zugriffen ist es weniger wichtig.

          Vorausgesetzt natürlich, man möchte die DB auch noch als DB nutzen können, und nicht nur als Blob-Speicher für serialisierte Objektnetze.

          Rolf

          --
          sumpsi - posui - clusi