Warum ordnet jeder Controller in einem Ordner und Ansichten in einem anderen an?

36

Ich mache mich bereit, die Biegung von Asp und in ein MVC-Framework, ASP.NET MVC oder Nancy zu nehmen. Wohin ich auch gehe, ich sehe Ordner für Controller / Module und Ordner für Ansichten. Ist dies nur ein pawlowscher Reflex, Dinge nach Typ aufzuräumen, oder gibt es eine tiefere Weisheit, die funktioniert? Ich habe ein kleines Proof-of-Concept-Projekt, in dem ich die Dateien, die ich wahrscheinlich zusammen öffne, zusammenspeichere, ein beträchtlicher Trost. Da sich diese Dateien wahrscheinlich auch gegenseitig aufrufen, können sie dies mit kürzeren, weniger spröden, relativen Links tun. Dieses Muster wird von mvc in Frage gestellt, da der Ordnerpfad nicht mehr automatisch dem URL-Pfad entspricht und in asp.net mvc die Projektvorlagen und das Routing die Aufrufe \ controller \ schism erzwingen.

Diese Microsoft-Seite stellt das Konzept der Bereiche vor. Es kann als ein Eingeständnis dafür verstanden werden, wie schwerfällig große Apps aufgrund dieser künstlichen Trennung werden.

Die Leute werden die "Trennung von Anliegen" ablehnen, aber die Trennung von Anliegen wird bereits durch separate Quelldateien erreicht. Es scheint mir kein konkreter Vorteil zu sein, diese eng gekoppelten Quelldateien an die anderen Enden der Ordnerstruktur zu senden.

Kämpft noch jemand dagegen? Irgendwelche Tipps?

bbsimonbb
quelle
3
Halten Sie es nicht für logisch, Back-End-Codedateien von Anzeigedateien zu trennen? Wenn wir bereits die Richtung eingeschlagen haben, warum nicht auch die relevanten CSS- und JavaScript-Dateien in denselben Ordner verschieben?
Alternatex
2
Wenn Sie Resharper erhalten, gelangen Sie mit F12 beim Aufruf von Viewin der Steuerung zur Ansicht, und die erste Option im Kontextmenü in der Ansicht führt Sie zur Steuerung, und das gesamte Problem mit der fehlenden Navigation wird behoben.
Pete Kirkham
4
@Alternatex Es tut mir leid, aber ich sehe nicht, wie ein Controller "Back-End" ist. Es ist eng mit seinen Ansichten verbunden. Die Ansicht ist ohne einen Controller nicht gut, der Controller ohne die Ansicht nicht verwendbar. Eines Tages möchten Sie sie zusammen löschen. Das ist für mich der beste Test, was in einem Ordner zusammengehört ??? Es sei denn, jemand kann mir einen besseren Weg zeigen?
bbsimonbb
2
Ansichten sind Präsentationsebenen. Controller sind Layer, die Services enthalten, die Objekte aus Ihrer Domain enthalten können, die Ihre Geschäftslogik enthalten und daher die Back-End-Logik Ihrer Anwendung enthalten. Ansichten bestehen nur aus trivialen Bedingungen und einfachen Schleifen für die Iteration über Sammlungen. Wenn Ihre Ansichten etwas anderes enthalten, machen Sie es falsch. Wie bei der regulären Struktur haben Sie das Back-End und das Front-End getrennt, was für mich eine bessere Struktur ist als die, die Sie vorschlagen.
Andy
10
Es mangelt also nicht an Leuten, die mir sagen, dass ein Controller Geschirr ist, also geht es in den Geschirrschrank. Ansichten sind Gläser, also gehen sie in den Glasschrank. Ich weiß, dass ein Controller Geschirr ist, aber ich schlage vor, es wäre großartig, einen Mittags- und einen Abendschrank zu haben, da es sich um Dinge handelt, die nur zum Mittag- oder Abendessen verwendet werden.
bbsimonbb

Antworten:

38

Ich würde gerne sagen, dass es Frachtkult-Programmierung ist , aber es gibt technische Gründe für diese Struktur. Asp.Net MVC verfolgte bei fast allen Aspekten eine Konvention über den Konfigurationsansatz. Standardmäßig durchsucht das Razor-Ansichtsmodul das ViewsVerzeichnis, um festzustellen, welche Ansicht vom Controller zurückgegeben werden soll. Es gibt jedoch ein paar Hacks , um eine andere Projektstruktur zu erhalten, und Microsoft bietet sogar die MVC-Funktion Areas an, mit der wir eine vernünftigere Projektstruktur erstellen können. Sie können auch eine eigene Ansichts-Engine implementieren , um anzugeben, wo nach Ansichten gesucht werden soll.

Warum sage ich, dass es Frachtkult-Programmierung ist und dass Sie diesbezüglich Recht haben? Onkel Bob hat mich überzeugt, dass die Verzeichnisstruktur des Projekts nicht besagen sollte, dass es sich um eine MVC-Anwendung handelt. Es sollte mir sagen, dass es sich um ein Ladengeschäft oder ein System für Urlaubsanträge handelt, oder was auch immer. Die Struktur und Architektur auf hoher Ebene sollten uns sagen, was dieses Ding ist und nicht, wie es implementiert wurde.

Kurz gesagt, ich glaube, Sie haben Recht, aber jede andere Verzeichnisstruktur würde einfach gegen das Framework kämpfen und mir vertrauen, wenn ich sage, dass Sie nicht versuchen möchten, das Asp.Net MVC-Framework dazu zu bringen, etwas zu tun, was es nicht war nicht entworfen, um zu tun. Schade, dass es eigentlich nicht mehr konfigurierbar ist.


Um schnell auf architektonische Bedenken einzugehen, sollten die Geschäftsmodelle (Geschäft, nicht Ansicht) und die DAL meines Erachtens in einem separaten Projekt / einer separaten Bibliothek gespeichert sein, das / die von Ihrer MVC-App aufgerufen wird.

Es ist nur so, dass der Controller wirklich sehr eng mit der Ansicht verbunden ist und wahrscheinlich zusammen modifiziert wird. Wir alle sollten uns den Unterschied zwischen der Kopplung über Abhängigkeit und der logischen Kopplung merken. Nur weil die Abhängigkeiten des Codes entkoppelt sind, ist er nicht weniger logisch gekoppelt.

Badeente
quelle
1
Die umfassende Art und Weise in den Rasierer sieht für Ansichten der Steuerung ist hier . Ich könnte nur durchhalten.
bbsimonbb
3
Ich sah Onkel Bob, wie vorgeschlagen, um 1,25 Uhr. Ich denke, wenn IT-Architekten Gebäude bauen würden, würden wir alle auf kleinen Floßgruppen leben, die auf einem See herumschwimmen. Das Leben wäre nicht unbedingt einfacher.
bbsimonbb
1
Es wird etwas komplizierter. Um Controller und Ansichten wirklich gemeinsam zu lokalisieren, müssen Sie den Ansichtspfad zur Laufzeit auflösen, um den Controller-Namespace einzuschließen. Hier ist, wie es geht .
BBSimonbb
1
Schauen Sie sich auch die funktionsorientierte Softwareentwicklung ( fosd.net ) an, die das akademische Gegenstück zu dem darstellt, was Onkel Bob beschreibt.
ngm
1
Conways Gesetz bei der Arbeit. Ich bin sicher, dass das bei Ihrer Firma @Flater funktioniert. Das Standard-MVC-Layout funktioniert in vielen Unternehmen, aber ich ziehe es immer noch vor, Dinge über die Semantik gegenüber der Syntax zu gruppieren. Die Unternehmen, für die ich arbeite, sind nach Produkten und nicht nach Rollen / Aufgabenbereichen organisiert. Ich glaube, das ist die Wurzel meiner Präferenz hier.
RubberDuck
9

Was auch immer der Grund ist, dies ist eine schlechte Praxis. Es ist sehr anti-OO, da Pakete oder Ordner (wie auch immer Sie sie nennen möchten) schwache Abhängigkeiten aufweisen sollten. Klassen (oder Dateien) in ihnen sollten starke Abhängigkeiten aufweisen.

Indem Sie alle Ansichten in einem Ordner und alle Controller in einem anderen Ordner ablegen, erstellen Sie zwei Pakete mit sehr enger Kopplung. Dies widerspricht dem Prinzip schwacher Abhängigkeiten zwischen Paketen.

Ein View und ein Controller sind zwei Hälften eines Ganzen und sollten zueinander gehören. Sie würden nicht einen Schrank für linke Socken und einen anderen für rechte Socken ziehen lassen.

Oliver Watkins
quelle
6

Um Ihre Frage zu beantworten: "Warum alle ...?" frage: Hier sind einige mögliche Gründe, obwohl ich nicht ganz sicher bin, welche Kombination eine echte Ursache ist, da es sich tatsächlich um eine subjektive Frage handelt

  • Replizieren der logischen Architektur (Modell, Ansicht, Controller) mit einer entsprechenden Ordner- und Namespace-Struktur

  • Befolgen Sie die ASP.net MVC-Projektvorlage aus Gründen der Benutzerfreundlichkeit

  • Nach Namespace gruppieren, da der Controllers/Ordner zu einem .ControllersNamespace führt

  • Möglicherweise werden einige Szenarien in DI / IoC aktiviert, in denen Controller-Klassen nur von einem Namespace abgefragt / gescannt werden, der / endet mit 'Controllers' (dies könnte falsch sein)

  • Damit T4-Vorlagen gescannt und Modelle und Steuerungen zum Generieren von Ansichten gerüstet werden können

Sie können immer Ihre eigene Konvention erstellen und befolgen, wenn es für Ihr Projekt Sinn macht, niemand kann / wird Sie aufhalten. Beachten Sie jedoch, dass bei der Arbeit in einem großen Projekt und / oder einem großen Team die Standardkonvention, die allen bekannt ist, möglicherweise die bessere Wahl ist (nicht unbedingt die richtige!).

Wenn Ihre Konvention leichter zu befolgen ist und die Produktivität nicht beeinträchtigt, dann tun Sie es auf jeden Fall! und vielleicht sogar ein oder zwei Blog-Posts darüber schreiben, um mit der Entwickler-Community in Kontakt zu treten und Feedback zu erhalten

Bishoy
quelle
2

Ein Grund, Ansichten und Controller in separaten Verzeichnissen zu speichern, besteht darin, dass Front-End- und Back-End-Entwickler an einem Projekt arbeiten. Sie können verhindern, dass Front-End-Entwickler auf Back-End-Code zugreifen (z. B. um die PCI-Konformität zu unterstützen und den Zugriff auf vertraulichen Code einzuschränken).

Ein weiterer Grund besteht darin, das Erstellen von "Designs" und das Austauschen aller Vorlagen zu vereinfachen, indem der Ansichtspfad geringfügig geändert wird.

Ein dritter Grund ist die Verwendung eines einfachen Verzeichnismusters bei der Angabe von Ansichten im MVC-Framework. Es ist einfacher, das Unterverzeichnis und die Datei anzugeben, als einen langen Pfad zu jeder Ansicht.

Die einzige "enge Kopplung" sollte sein:

  1. Variablen, die von der Steuerung in die Ansicht gesendet werden.
  2. Formularfelder oder Aktionen in der Ansicht, die an den Controller zurückgesendet werden.

Ich verwende einen generischen Controller und versuche, Variablennamen in der generischen Ansicht beizubehalten, sodass viele Ansichten denselben Controller und viele Controller dieselbe Ansicht verwenden können. Aus diesem Grund ziehe ich es vor, die Ansichten völlig getrennt zu halten. Im Modell können Sie jedes "Ding" in Ihrer Anwendung unterscheiden - es können Objekte mit einer Liste von Eigenschaften und Methoden sein, um auf diese Eigenschaften zuzugreifen oder sie zu ändern.

Bei eng gekoppeltem Code besteht ein Ansatz, der für Sie funktionieren könnte, darin, alle Dateien, die Teil eines Pakets oder "Moduls" sind, in einem Verzeichnis mit Namespaces zusammenzuhalten. Anschließend können Sie Ihre Rohvorlagen mit einem Skript in das Hauptverzeichnis "views" kopieren oder "kompilieren". Beispielsweise:


    lib/my-namespace/my-package/
        -> controllers/
        -> models/
        -> views/
            -> theme/
               -> template-name1
    app/compiled_views/theme/
        -> url/path/template-name1

Wenn Sie die Struktur eines vorhandenen Themas ändern möchten, werden die Paketverzeichnisse leider häufiger ein- und ausgeblendet, um die Ansichten zu aktualisieren.

Bedenken Sie, dass Ansichten nur eine Möglichkeit zum Formatieren von Daten darstellen, unabhängig davon, ob es sich um JSON-, XML-, CSV- oder HTML-Daten handelt. Dies ist besonders hilfreich, wenn Ihre Anwendung auch als API fungieren soll. Versuchen Sie, die Ansicht mithilfe generischer Variablennamen von den Daten zu entkoppeln, damit Sie dieselbe Vorlage für viele Controller oder Modelle verwenden können (oder verwenden Sie Includes, um die Menge an Code zu minimieren, die Sie verwalten müssen).

Frank Forte
quelle
1

Nicht unbedingt jeder macht das. Zum Beispiel hat das Django-Framework von Python das Konzept einer App, bei der Untermodule Ihrer Anwendung in ihren eigenen Verzeichnissen mit ihren eigenen Modellen und Ansichten und Vorlagen leben (Ansichten nennt Django im Wesentlichen Controller). Zufällig bevorzuge ich diese Vorgehensweise, da ich eine "App" auf einfache Weise packen und projektübergreifend wiederverwenden kann, indem ich sie einfach in die Liste der Apps in meinen Projekteinstellungen aufnehme. Es ist auch einfacher herauszufinden, wo sich verschiedene Teile befinden. Wenn ich mir die Datei urls.py ansehe und etwas Ähnliches url(r'^users/', include('my_site.users.urls'))sehe, weiß ich, dass das Modul den my_site.usersgesamten Code enthält, der die Benutzer behandelt. Ich weiß, wie die Module aussehen my_site.users.viewsund my_site.users.modelswann ich sehen möchte, wie Benutzer erstellt und authentifiziert werden. Ich weiß, dass alle meine Routen in definiert sind my_site.users.url.

Auch wenn es generisch genug ist, kann ich dieses Modul wahrscheinlich an anderen Standorten verwenden, indem ich die Konfiguration ändere oder es als Bibliothek packe und als OSS veröffentliche.

Pavel Penev
quelle
1

Denken Sie daran, es ist die von Microsoft empfohlene Methode , um die Controller und Ansichten in unterschiedlichen Ordnern zu speichern, sodass viele der empfohlenen Struktur folgen.

  1. Ein Grund dafür könnte sein, dass Controller immer keine Eins-zu-Eins-Beziehung zu Ansichten haben, insbesondere können die Teilansichten von Controllern gemeinsam genutzt werden.
  2. Ein weiterer Grund könnte sein, dass Sie, wenn Ihr Projekt wächst, Controller und Komponententests in ein anderes Projekt ziehen möchten, aber es ist ziemlich schwierig, dasselbe für Views und Views / js / css zu tun, die zusammengehören, da sie sich gegenseitig referenzieren.

Trotzdem gibt es viele Posts, in denen es darum geht, es auf deine Art und Weise zu tun, wie zum Beispiel diese .

Tieffliegender Pelikan
quelle
"Es ist der von Microsoft empfohlene Weg" ... Können Sie klarstellen, was Sie damit meinen? Gibt es einen aktuellen, maßgeblichen MS-Artikel dazu? Oder ist das nur die Standardprojekteinrichtung für eine MVC-App? Und wenn Sie sich auf das Letztere stützen, ist es nicht möglich, dass das Standard-MVC-Projekt so eingerichtet ist, wie es ist, weil es so ist, wie "jeder" es tut?
Svidgen
1
Basierend auf dem Artikel msdn.microsoft.com/en-us/library/… steht dort "Controller, der empfohlen wird" und so weiter für die Ansichten usw.
Niedriger fliegender Pelikan
0

Für die Aufzeichnung

Warum sage ich, dass es Frachtkult-Programmierung ist und dass Sie diesbezüglich Recht haben? Onkel Bob hat mich überzeugt, dass die Verzeichnisstruktur des Projekts nicht besagen sollte, dass es sich um eine MVC-Anwendung handelt. Es sollte mir sagen, dass es sich um ein Ladengeschäft oder ein System für Urlaubsanträge handelt oder was auch immer. Die Struktur und Architektur auf hoher Ebene sollten uns sagen, was dieses Ding ist und nicht, wie es implementiert wurde.

Frage: Wer hat Zugriff auf den Code? Programmierer. Interessieren sich Endbenutzer für den Code? Nein. Und was ein Programmierer macht, Code. Genauer gesagt, Klassen, die auf Typen basieren (Controller, Service, Modell usw.). Daher ist es sinnvoll und einfach, einen Code zu debuggen, wenn Sie in der Lage sind, einen Code anhand des Codetyps zu finden, anstatt anhand des Verhaltens des Codes. Nehmen wir an, ein Teamprojekt ist für den Controller, das andere für das Modell, das andere für das Dao und das andere für die Ansicht zuständig. Es ist einfach, das Projekt in Teile zu unterteilen. Ein guter Code ist ein Code, der leicht zu debuggen ist, kein Syntaxzuckercode. Onkel Bob hat wieder Unrecht.

Der Versuch, das Verhalten des Projekts (einer Ladenfront) nachzuahmen, ist Frachtkult.

Magallane
quelle
3
Wenn ich programmiere, interessieren mich Funktionen am meisten, nicht Typen. Wenn ich sehe, dass eine Funktion nicht wie erwartet funktioniert, weiß ich, dass im Code für diese Funktion etwas nicht stimmt, obwohl ich nicht unbedingt weiß, um welche Art von Code es sich handelt.
Hören Sie auf, Monica
1
„Nehmen wir an, ein Teamprojekt ist für den Controller zuständig, ein anderes für das Modell, ein anderes für das Dao.“ Solch ein Team wird es schwer haben, irgendetwas zu versenden, und wenn sie dies tun, werden Kommunikationskosten und Fehler weitaus höher ausfallen.
RubberDuck
Wie in einer Kommentarkette unter der akzeptierten Antwort festgelegt, haben Sie einen Punkt, aber nur in bestimmten Fällen. Wenn sich ein Unternehmen auf MVC-Projekte konzentriert, die es an viele verschiedene Kunden verkauft, ist es für die Wiederverwendbarkeit sinnvoll, eine MVC-Struktur beizubehalten. Wenn sich ein Unternehmen auf eine Nische konzentriert (z. B. Webshops) und möglicherweise viele verschiedene Technologien einsetzt, ist eine Webshop-orientierte Struktur sinnvoller. Dies ist eine praktische Anwendung von Conways Gesetz . Der Code (und damit auch die Projektstruktur) sollte der Unternehmensstruktur folgen.
Flater
@RubberDuck: Sie können in beiden Fällen ein Argument für zusätzliche Kosten vorbringen. Sie haben Recht, wenn verschiedene Leute unterschiedliche technische Komponenten ausführen, haben Sie die Kommunikation mit der Geschäftslogik verbessert. Wenn Sie jedoch unterschiedliche Mitarbeiter haben, die unterschiedliche Funktionen vollständig implementieren, kann es zu höheren Kosten kommen, wenn Sie sicherstellen, dass alle an Bord sind (qualifiziert + zustimmend), dass Sie denselben technischen Ansatz verwenden. In jedem Fall ist ein Kommunikationsaufwand erforderlich, um sicherzustellen, dass die Mitarbeiter zusammenarbeiten.
Flater
Ja, und Handoffs kosten immer mehr als ein einzelnes Entwicklerpaar, das ein Feature-End-to-End-IME implementiert.
RubberDuck