Thomas: ein Hilfestellung

Hallo zusammen,

ich habe ein große Bitte und hoffe das mir hier jemand weiterhelfen kann.

Ich plane gerade ein größeres Projekt in PHP.
Ich möchte mich das erste mal an das MVC Prinzip halten.
Außerdem soll alles sauber OO programmiert werden.

Was ich von euch bräuchte wäre eine Grundstruktur ein Stütze.

Im Moment (bin gerade so am herumprobieren und dabei fallen einem immer neue Dinge auf und ein) habe ich folgende Struktur:

Projektname
.modules
..controllers
...BestandController.php
..database
..models
...BestandModel.php
..standard
...Model.php
..views
...template
index.php

Was meint ihr dazu?
Müssen die Views als Klasse bestehen? View sind doch so gesehen nur einfache Templates oder?

Im Ordner "standard" sind die Elternklassen wie z.b. "class Model". BestandModel erbt dann von Model. Ist das gut?

Jetzt wollte ich vielleicht auch gleich mal mit Interfaces arbeiten. Wo in welchem Verzeichniss würdet ihr die reinpacken?

Mit Namespaces versuche ich mich auch gerade und erstelle die Namespaces genauso wie die Ordner Struktur.

Sind meine Ansätze richtig? Könnt ihr vielleicht ein schönes Grundgerüst bieten?

Vielen Dank schonmal.
Grüße

  1. Hi!

    ..database
    ..models
    ...BestandModel.php

    Was ist Aufgabe des database-Verzeichnisses?

    Müssen die Views als Klasse bestehen? View sind doch so gesehen nur einfache Templates oder?

    Prinzipiell muss gar nichts. Patterns sind Lösungsvorschläge, keine Implementierungsvorschriften. Ob du OOP dafür verwendest oder nicht oder nur teilweise, ist nicht relevant. Und es hindert dich auch niemand daran, ein Pattern modifiziert zu verwenden.

    Im Ordner "standard" sind die Elternklassen wie z.b. "class Model". BestandModel erbt dann von Model. Ist das gut?

    Ich wüßte bei dieser pauschalen Frage keine Argumente dafür oder dagegen.

    Jetzt wollte ich vielleicht auch gleich mal mit Interfaces arbeiten. Wo in welchem Verzeichniss würdet ihr die reinpacken?

    Was versprichst du dir von Interfaces? Etwas einzusetzen, vielleicht weil es in aller Munde ist, ist unsinnig. Was bringt dir das Interface, was eine Basisklasse nicht zu leisten vermag? Im Allgemeinen kann man Interfaces verwenden, wenn die Funktionalität gleich bleiben soll, die Implementation aber grundverschieden gelöst werden soll. Ansonsten reicht eine Basisklasse mit Ableitungen.

    Mit Namespaces versuche ich mich auch gerade und erstelle die Namespaces genauso wie die Ordner Struktur.

    Denkst du innerhalb deines Projektes wird es zu Namensdopplungen in unterschiedlichen Bereichen kommen? Bringt es aus anderen Gründen etwas?

    Sind meine Ansätze richtig? Könnt ihr vielleicht ein schönes Grundgerüst bieten?

    Es kommt ja auch darauf an, ob du alles selbst entwickeln möchtest, oder ein Famework verwendest, das eine bestimmte Verzeichnisstruktur vorgibt. Such dir ein paar Frameworks, schau nach, wie sie dies oder jenes umsetzen und vorgeben und lass dich von ihnen inspirieren.

    Lo!

    1. ..database
      Was ist Aufgabe des database-Verzeichnisses?

      beinhaltet eine Klasse MyDB die PDO instanziert.
      Dazu ein Klasse die mir per Aliasname einen SQL Befehl zurück liefert der im Unterverzeichnis "sql" von "database" in einer Datei "Aliasname.sql" steht.

      Müssen die Views als Klasse bestehen? View sind doch so gesehen nur einfache Templates oder?

      Prinzipiell muss gar nichts.

      Ja das ist richtig. Mir geht es auch darum was hier klüger ist.
      Alles in Klassen zu packen und dann bei den Templates eine Ausnahme zu machen ist doch auch irgendwie "doof" :)

      Jetzt wollte ich vielleicht auch gleich mal mit Interfaces arbeiten. Wo in welchem Verzeichniss würdet ihr die reinpacken?

      Im Allgemeinen kann man Interfaces verwenden, wenn die Funktionalität gleich bleiben soll, die Implementation aber grundverschieden gelöst werden soll. Ansonsten reicht eine Basisklasse mit Ableitungen.

      Das wäre doch bei meinem Model usw. der Fall oder? Die Daten können ja über unterschiedlichste Wege kommen. z.b. BestandModel aus der DB und UserModel aus einer Textdatei. Wenn ich das sicher programmieren möchte wäre doch hier ein Interface angebracht weil eine Basisklasse dafür dann wohl nicht geeignet wäre?

      Mit Namespaces versuche ich mich auch gerade und erstelle die Namespaces genauso wie die Ordner Struktur.

      Denkst du innerhalb deines Projektes wird es zu Namensdopplungen in unterschiedlichen Bereichen kommen? Bringt es aus anderen Gründen etwas?

      Hmm... eigentlich nicht. Eigentlich ist es unnütz in meinem Fall :)
      Ich wollte es halt gleich richtig machen wenn ich mir schon mal die Mühe mach.

      Sind meine Ansätze richtig? Könnt ihr vielleicht ein schönes Grundgerüst bieten?

      Such dir ein paar Frameworks, schau nach, wie sie dies oder jenes umsetzen und vorgeben und lass dich von ihnen inspirieren.

      Das hab ich natürlich schon gemacht und mir auch schon ein paar Inspirationen geholt.

      Lo!

      Vielen Dank für dein Antwort

      1. Hi!

        ..database
        beinhaltet eine Klasse MyDB die PDO instanziert.
        Dazu ein Klasse die mir per Aliasname einen SQL Befehl zurück liefert der im Unterverzeichnis "sql" von "database" in einer Datei "Aliasname.sql" steht.

        Du sammelst also an einer separaten Stelle alle SQL-Statement-Strings, so dass du an mehreren Stellen arbeiten musst, wenn du mal beispielsweise einen Parameter hinzufügen willst. Im SQL-String den Platzhalter einfügen und anderswo das Handling dazu. Das klingt unübersichtlich.

        Alles in Klassen zu packen und dann bei den Templates eine Ausnahme zu machen ist doch auch irgendwie "doof" :)

        Nicht "doofer" als dass ein Controller mit Eingabedaten, ein Model mit einer Datenbank und eine View mit Template-Dateien hantiert. Vermutlich wirst du aber einige Hilfsfunktionen in der View haben wollen, die sich zum Beispiel um das korrekte Behandeln von Werten beim Einfügen in das Template beschäftigen, die HTML-Elemente (für Formulare oder Datagrids vielleicht) erstellen, und so weiter. Da brauchts dann Code dafür, der auch gut in Klassen untergebracht werden kann.

        Schau mal übern Tellerrand :-) und dir ASP.NETs MVC-Implementation an. Bei jenem Tutorial reicht es, wenn du es überfliegst. Projekt erstellen, Datenbank erstellen - geschenkt. Model erstellen geschieht auch mit Clicks, das Ergebnis ist automatisch generierter Code (für das einfach Beispiel als Model ausreichend) - ebenfalls geschenkt. Controller erstellen - eine Menge selbst geschriebener C#-Code. Dann kommt die View, um die Datensätze zu listen. Und die ist erst einmal nur ein Template mit eingestreutem Code, quasi PHP-like. Aber auch da steckt eine Klasse dahinter, wie am Anfang von Listing 3 mit Inherits="System.Web.Mvc.ViewPage<...> zu sehen ist. Dieses Template wird von .NET beim ersten Request in C#-Code übersetzt und compiliert. Auf den ersten Blick sieht eine View anders aus als M und C, dem Prozessor und dem Seitenbesucher ist das aber letztlich egal. Der Rest vom Tutorial behandelt das Bearbeiten von Daten - eine Wiederholung von Controller- und View-Bearbeitung - auch geschenkt.

        Im Allgemeinen kann man Interfaces verwenden, wenn die Funktionalität gleich bleiben soll, die Implementation aber grundverschieden gelöst werden soll. Ansonsten reicht eine Basisklasse mit Ableitungen.
        Das wäre doch bei meinem Model usw. der Fall oder? Die Daten können ja über unterschiedlichste Wege kommen. z.b. BestandModel aus der DB und UserModel aus einer Textdatei. Wenn ich das sicher programmieren möchte wäre doch hier ein Interface angebracht weil eine Basisklasse dafür dann wohl nicht geeignet wäre?

        Was ist das gemeinsame zwischen deinen Models? Welche Methoden sollen denn alle Models gemeinsam haben? getData()? Scheint mir nicht sehr sinnvoll zu sein. Üblicherweise behandelt jedes Model ein eigenes Thema mit von den anderen Models unterschiedlichen Datenstrukturen (getPerson(), getCompany(), getWhatever()). Eine View ist auch auch spezialisiert auf die Daten, die sie bekommt und kann kaum pauschal aus einem beliebigen Model Content erstellen.

        Ich wollte es halt gleich richtig machen wenn ich mir schon mal die Mühe mach.

        Gleich richtig bedeutet nicht, aufblähen nur weil es geht. Performant muss es am Ende einerseits sein, wartbar andererseits. Kompromisse zu suchen bleibt da nicht aus.

        Lo!

        1. Hi!

          ..database
          Unterverzeichnis "sql"
          Das klingt unübersichtlich.

          Findest du? Ich habe das als Wartungsfreundlicher empfunden, außerdem verschwinden die SQL Statements aus meinem Code.
          Man könnte zum Beispiel mal hergehen und alle SQL Statements auf Performance und Optimierung prüfen und hat sie so alle in einem Ordner vorhanden.
          Außerdem sieht man so besser wie viele Statements man in seinem Projekt verbaut hat.
          Für die Übersichtlichkeit sind aber sinnvolle Dateinamen Pflicht.

          Schau mal übern Tellerrand :-) und dir ASP.NETs MVC-Implementation an.

          Das mach ich, danke.

          Im Allgemeinen kann man Interfaces verwenden, wenn die Funktionalität gleich bleiben soll, die Implementation aber grundverschieden gelöst werden soll. Ansonsten reicht eine Basisklasse mit Ableitungen.
          Das wäre doch bei meinem Model usw. der Fall oder?

          getData()? Scheint mir nicht sehr sinnvoll zu sein.

          Genau das hatte ich eigentlich vor.
          getData, setData, changeData, deleteData ... so in der Art.
          Das wäre ja dann für jedes Model notwendig aber mit anderem Inhalt.

          Eine View ist auch auch spezialisiert auf die Daten, die sie bekommt und kann kaum pauschal aus einem beliebigen Model Content erstellen.

          Zum Beispiel eine View die ein Tabelle aus einem Array erzeugt. Das wäre doch etwas was sozusagen von jedem Model benutzt werden kann.

          Ich wollte es halt gleich richtig machen wenn ich mir schon mal die Mühe mach.

          Gleich richtig bedeutet nicht, aufblähen ... Kompromisse zu suchen bleibt da nicht aus.

          Ja, man will halt immer alles auf einmal :)

          Lo!

          Gruß Thomas

          1. Hi!

            Ich habe das als Wartungsfreundlicher empfunden, außerdem verschwinden die SQL Statements aus meinem Code.
            Man könnte zum Beispiel mal hergehen und alle SQL Statements auf Performance und Optimierung prüfen und hat sie so alle in einem Ordner vorhanden.

            Ist wenig realistisch. "Heute optimiere ich mal alle Statements." :-) Eher kommt doch vor, dass du irgendwo einen Engpass siehst und diesen gezielt bearbeitest. Dann findest du dazu einen Bezeichner, musst anderenorts diesen Bezeichner wiedersuchen und das was eigentlich eng zusammenarbeiten soll hat ein paar Schnittstellen dazwischen, die Kosten verursachen - sei es Performance (wenn auch gering) oder insgesamt erhöhte Komplexität mit zweifelhaftem Nutzen.

            Du kannst es aber gern mal auf deine Weise probieren, man lernt ja auch aus negativer Erfahrung. Andererseits kann sich dadurch auch was neues sinnvolles ergeben, das der Betriebsblinde sonst nicht erfahren würde.

            Außerdem sieht man so besser wie viele Statements man in seinem Projekt verbaut hat.

            Diese Information halte ich für wenig nützlich.

            Genau das hatte ich eigentlich vor.
            getData, setData, changeData, deleteData ... so in der Art.
            Das wäre ja dann für jedes Model notwendig aber mit anderem Inhalt.

            Nicht jedes Model hat genau je eine solche Methode. Die Models sind die Arbeiter in deiner Firma. Es mag einige geben, die Daten in allen 4 Facetten zu genau einem Thema verarbeiten. Andere haben mehrere (Teil-)Aufgaben oder komplett andere. Das Bodenpersonal räumt nur auf, der Wachschutz kontrolliert den Zugang zum Unternehmen, der Betriebsarzt kümmert sich um die Gesundheit, Einkauf und Vertrieb handeln mit externen Parteien und das Marketing sorgt fürs Brimborium.

            Models müssen aber auch keine Universalmonster sein. Eine Model-Klasse kann auch Aufgaben delegieren. Wenn du Zeit und Muße hast, verweise ich nochmal auf ASP.NETs MVC-Implementation. Ganz unten steht eine Tutorial-Serie zu einem Contact-Manager. Vorab: Es ist nicht immer sinnvoll, alles anderswo gesehene 1:1 nach PHP übertragen zu wollen. Jedes System hat seine eigene Philosophie und andere Möglichkeiten, Dinge zu implementieren. In der erwähnten Tutorial-Serie jedenfalls ist in Interation 3 noch alles im Controller angesiedelt, in Iteration 4 werden Aufgaben in Service Layer und Repository ausgelagert, vor allem um sie kapseln und testbar machen zu können. Dort werden auch Interfaces verwendet, aber beispielsweise mit dem Ziel, auch mal einem Service-Layer ein Dummy-Repository unterjubeln zu können, damit Unit-Tests nicht vom Arbeitswillen eines DBMS abhängig sind, sondern sich ganz auf die eigentliche Aufgabe konzentrieren können. Service Layers und Repositorys behandeln jeweils ein Thema, aber es gibt keine generellen Basisklassen oder Interfaces, weil ihre Aufgaben doch zu verschieden sind.

            Zum Beispiel eine View die ein Tabelle aus einem Array erzeugt. Das wäre doch etwas was sozusagen von jedem Model benutzt werden kann.

            Das wäre meines Erachtens keine (eigenständige) View sondern eine Hilfsfunktion, derer sich eine View bedienen kann aber nicht muss. Und nicht alle vom Model erledigten Aufgaben erfordern eine tabellarische Darstellung des Ergebnisses. Ein Interface, das zu (großen) Teilen wegen Nichtverwendung nicht implementiert ist, ist auch nicht sehr sinnvoll.

            Ein Datagrid, ein Pager, ein Formulargenerator - alles Funktionalität, die zwar öfter verwendet wird, aber nicht zwangsläufig. Dafür muss also nicht überall eine Vorbereitung getroffen werden.

            Lo!