Wie organisieren Sie Ihr MVC-Framework, während Sie Module / Plugins unterstützen? [geschlossen]


17

Es gibt zwei Haupt-Codebasisstrukturen, die ich in Bezug auf MVC-Frameworks gesehen habe. Das Problem ist, dass sie beide einen organisatorischen Fehler haben, der mit ihnen einhergeht.

Standard MVC

/controller
/model
/view

Problem: Keine Trennung von verwandten Komponenten (Forum, Blog, Benutzer, etc ..)

Modularer MVC

/blog
    /controller
    /model
    /view
/user
    /controller
    /model
    /view
/forum
    /controller
    /model
    /view

Bei der Auswahl des modulbasierten Systems treten Probleme auf.

  • Lange Namen (Forum_Model_Forum = forum / model / forum.php) (Like Zend)
  • Nach Dateisystemen suchen, is_file()um herauszufinden, in welchem ​​Ordner sich das Forum befindet. (Wie Kohana)

Gibt es andere MVC-Strukturen, die beim Versuch, verschiedene Module zu trennen, gut funktionieren? Gibt es Vorteile von diesen Strukturen, die ich vermisse?


1
Ich möchte auch hinzufügen, dass ich eine Struktur möchte, die PSR-0-kompatibel ist, damit ich bei Bedarf auch Bibliotheken wie Zend und Doctrine verwenden kann.
Xeoncross

Antworten:


9

Versuchen:

/blog 
    /controller
    /view
/user
   /controller
    /view 
/forum
    /controller
    /view
/model
    User
    BlogPost
    Comment
    ....

Ihre Modelle sind das Herzstück Ihrer Anwendung. Sie sollten sie als eigenständiges Paket entwerfen und codieren. Die Controller sind nur Clients Ihres Modells, die Benutzeraktivitäten in Aktionen für Ihr Modell umsetzen. Eine Ansicht ist nur eine Möglichkeit, Daten aus Ihrem Modell anzuzeigen. Wenn Ihre Anwendung wächst, können Sie die Clients noch weiter vom Modell trennen:

WebClient
    /blog 
        /controller
        /view
    /user
       /controller
        /view 
    /forum
        /controller
        /view
CommandLineClient
    delete_spam_posts_script
RestApiClient

/model
    User
    BlogPost
    Comment
    ....

Dies sollte deutlich machen, dass Sie mehrere Clients haben können, die alle auf die eine oder andere Weise mit einem einzelnen Modell interagieren.


+1, weil ich Ihrer Erklärung der MVC-Komponenten und ihrer Funktionsweise vollkommen zustimme. Der Vorteil eines Moduls besteht jedoch darin, dass Sie Module importieren können, die von anderen Benutzern erstellt wurden. Wenn sich die Modelle also außerhalb des Modulpfads befinden, wird das Ziehen und Ablegen verringert. Ihre Methode ist jedoch sehr sinnvoll für Anwendungen, die keine externen Plugins oder Module verwenden.
Xeoncross

@Xeoncross das stimmt, ich habe die Wiederverwendbarkeit hier nicht wirklich berücksichtigt. Wenn dies eine Anforderung ist, können Sie in der Tat einen Schritt weiter gehen und beispielsweise ein 'Benutzer'-Modul verwenden, das das Benutzermodell mit seinem Controller gruppiert, und ein Blog-Modul, das das BlogPost- und das Kommentar-Modell mit seinen Controllern gruppiert. Wie immer: es kommt auf den Kontext an :-)
Mathias Verraes

2

;)

Ich habe die beste Struktur für ein MVC / HMVC-Framework gefunden. Hauptsächlich müssen Sie Basis-Controller / Modelle / Ansichten verwenden ... aber für die einzelnen Komponenten der Kursmodule ...

In meinem MVC / HMVC-Framework sieht die Struktur also so aus:

/application
  controllers/
  models/
  views/
  modules/
    blog/
      controllers/
      models/
      views/ 
    user/
      controllers/
      models/
      views/
    forum/
      controllers/
      models/
      views/

Auch wenn ich brauche, füge ich in Modulen Bibliotheken, i18n oder Helfer hinzu.

Die Namenskonvention ist einfach, für Controller und Modelle füge ich die Suffixe _Controller und _Model hinzu. Für Controller und Modelle aus den Modulen füge ich zusätzlich ein Präfix mit Modulname hinzu, zum Beispiel. controller Profil im Modul User wird als User_Profile_Controller benannt.

So finden Sie ganz einfach und schnell das, was Sie brauchen.


1

Problem: Lange Namen (Forum_Model_Forum)

Eine systematische Benennung der Klassen hilft, Namenskonflikte zwischen Komponenten zu vermeiden. Lange Benennungen von Klassen verursachen wahrscheinlich keine schwerwiegenden Leistungseinbußen. Ich finde dieses Benennungsschema beim Codieren ziemlich hilfreich, weil man leicht sieht, was woher kommt.

Dateisystemsuche (welcher Ordner hat das Forenmodell?).

Dies hängt stark davon ab, wie das System implementiert wurde. Die Struktur des Dateisystems folgt jedoch normalerweise einer Konvention, die den sofortigen Zugriff auf die richtige Komponente ohne umfangreiche Dateisystemsuchen ermöglicht.

Angenommen, die Forum-Komponente soll verwendet werden:

Die Info:

  • Komponentenname: Forum
  • Controller-Name: Index

    $ controller_path = BASIS. 'module /'. $ component_name. '/ controller /'. $ controller_name. '.php';

Es ist auch wichtig zu beachten, dass beim Booten einer typischen Website buchstäblich Hunderte von Dateisystemabfragen auftreten, sodass das Hinzufügen einiger nicht schaden wird.


In der Tat sind Back-Ends keine clientseitigen Apps, die schnell gestartet werden müssen. Sie können sich die Zeit nehmen, die zum Konfigurieren der Laufzeit erforderlich ist. Guter Punkt.
Patrick Hughes

0

Ich habe mit Websites gearbeitet, die mit dem ersten "Standard MVC" begannen, aber schließlich zum "Modular MVC" wurden.

Wenn Sie eine kleine Website betreiben und wenig Erfahrung haben, können Sie mit der "Standard-MVC" beginnen. Wenn Sie bereits wissen, dass die Website sehr komplex und umfangreich sein wird, müssen Sie sich an die "Modulare MVC" gewöhnen. Es wird am Anfang ein wenig schwierig sein, aber irgendwann werden Sie sich daran gewöhnen es.


0

Ich arbeite selbst an einem Framework und benutze eine Kombination aus modulbasierter und Freiform-Verzeichnisstruktur. Meine Standardstruktur für Site-Code unter Verwendung des Frameworks lautet:

/Configuration (stored a bunch ini files for security related information like passwords)
/Functions (stores file(s) with standard procedural functions)
/Libraries (general use classes)
/Models (all models go here)
/Modules (each module refers to one controller
/Modules/Site (controller class store in this folder if there is a controller)
/Modules/Site/Views (views for the controller)

Sie können auch einen Modulordner haben, der sich nicht auf einen Controller bezieht, und es gibt standardmäßig einen Aufruf Core, der zum Speichern von standortweiten Vorlagen wie Kopf- und Fußzeile verwendet wird. Dies gibt mir das Beste aus beiden Welten. Sie können leicht erkennen, wo sich der Controller befindet, da es einen Controller pro Ordner gibt. Bei Klassen wie Modellen müssen Sie jedoch nicht danach suchen, wo sich die Dateien befinden, da sie sich in einem Verzeichnis befinden (wodurch auch die Namen der Modelle bereinigt werden). .

Die Art und Weise, wie ich Dateien lade, ist etwas anders, da der Benutzer die verschiedenen Verzeichnisse konfigurieren kann, in denen Klassen gespeichert werden können. Daher analysiere ich zunächst die Verzeichnisse und speichere alle Speicherorte der Klassendateien in einer JSON-Datei alle anderen Anfragen (obwohl ich nach Verbesserungsmöglichkeiten suche).


0

Die Antwort auf diese Frage wurde durch den PSR-0-Vorschlag vorgegeben, den alle großen Systeme gerade anzupassen beginnen oder jetzt angenommen haben.

Die Struktur ist:

\Doctrine\Common\IsolatedClassLoader => /Doctrine/Common/IsolatedClassLoader.php
\Symfony\Core\Request => /Symfony/Core/Request.php
\Zend\Acl => /Zend/Acl.php
\Zend\Mail\Message => /Zend/Mail/Message.php

Das bedeutet, dass Sie nichts tun können, um lange Dateinamen zu korrigieren:

$controller = new \Blog\Controller\Archive => /Blog/Controller/Archive.php

/Blog
    /Controller
        Archive.php
    /Model
    /View
/User
    /Controller
    /Model
    /View
/Forum
    /Controller
    /Model
    /View

Dies bedeutet auch, dass Sie dumme Dateien in Groß- und Kleinschreibung anstelle von Kleinbuchstaben verwenden müssen (wenn Sie dies nicht tun, funktionieren Bibliotheken von Drittanbietern nicht).


0

Mathiases Lösung macht großen Sinn. Und die Verwendung seiner Ordnerstruktur verhindert nicht, dass steckbare Inhalte vorhanden sind, zum Beispiel das Hinzufügen einer unabhängigen / gallery / könnte so aussehen

WebClient
    /blog 
        /controller
        /view
    /user (uses /model/User/)
       /controller
        /view 
    /forum
        /controller
        /view
    /gallery
        /controller
        /view
        /model
CommandLineClient
    delete_spam_posts_script
RestApiClient

/model
    User
    BlogPost
    Comment

Jetzt haben wir ein gemeinsames "Modell" und wenn nötig unabhängige

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.