Sollte ich meine Ordner nach Geschäftsdomäne oder technischer Domäne organisieren?

19

Wenn ich beispielsweise eine MVC-ähnliche Architektur verwende, welche Ordnerstruktur soll ich verwenden:

domain1/
    controller
    model
    view
domain2/
    controller
    model
    view

Oder:

controllers/
    domain1
    domain2
models/
    domain1
    domain2
views/
    domain1
    domain2

Ich habe Dateierweiterungen absichtlich weggelassen, um diese Frage sprachunabhängig zu machen.

Persönlich würde ich es vorziehen, nach Geschäftsbereichen zu trennen (Bauchgefühl), aber ich sehe, dass die meisten / viele Frameworks nach technischen Bereichen getrennt sind. Warum sollte ich eine der anderen vorziehen?

Florian Margaine
quelle
2
Frameworks richten sich an Entwickler, nicht an Geschäftsanwender. Entwickler werden voraussichtlich mehr bequem sein mit technisch orientierten Ansatz und Frameworks das berücksichtigen - das kann der Grund sein für das, was Sie beobachten
gnat

Antworten:

15

Ich denke, das hängt von einem bestimmten Projekt ab.

Wenn beispielsweise die verschiedenen Geschäftsdomänen völlig unabhängig voneinander sind, würde ich sie nach Geschäftsdomänen organisieren.

Wenn es jedoch gemeinsamen Code zwischen den Geschäftsdomänen gibt oder die Geschäftsdomänen unterschiedliche Varianten derselben Codebasis sind, erscheint es logischer, nach technischen Domänen zu organisieren. Und wenn Sie irgendeine Art von objektorientierter Sprache verwenden, können Sie Ihre generischen Controller, Modelle usw. wahrscheinlich in Ihre unternehmensspezifischen Dateien einteilen, um sie dünner zu machen.

Es gibt auch eine (goldene) Mitte zwischen den beiden - entfernen Sie gemeinsam genutzten Code in eine eigene Domain und verwenden Sie diesen in anderen Domains. Dies gibt Ihnen das Gefühl, ein Layout zu haben, ermöglicht jedoch den gemeinsamen Code zwischen Geschäftsdomänen.

Domain1              # This domain changes bits of standard MVC code
  controllers
  models
  views
Domain2              # this domain only modifies views, all else is standard
  views
Shared               # Here is the better part of code base
  controllers
  models
  views

PS. Ich denke, dass die meisten Frameworks nach technischen Domänen organisiert sind, nur weil sie dazu neigen, zu erwarten, dass Sie verschiedene Geschäftsdomänen nur dann in ein einziges Projekt mischen, wenn Sie gemeinsamen Code haben und andernfalls separate Projekte erstellen würden.

BEARBEITEN:

Angenommen, es gibt eine Web-App, die das Warenlager eines Unternehmens verwaltet. In allgemeiner Form trifft dies möglicherweise auf viele Unternehmen zu, aber jedes von ihnen hat möglicherweise einige Besonderheiten, die nicht erfüllt werden, und verbietet das Kaufen. Beispielsweise hat eines von ihnen Tablets für die Gabelstapler bereitgestellt und benötigt eine spezielle Ansicht für sie, während ein anderes dies wünscht Elemente in drei Ebenen anstatt in zwei Ebenen zu organisieren.

Sie könnten natürlich das Projekt für jedes dieser Unternehmen teilen. Wenn es das Framework / die Sprache zulässt, können Sie Unterklassen oder Plugins usw. verwenden, um Teile des allgemeinen Projekts an die Bedürfnisse jedes Kunden anzupassen und sie in den Business Domain-Layouts zu organisieren.

Wenn z. B. ein generisches Projekt nur das Element selbst nach JSON exportiert, kann Domain1 den Controller in eine Unterklasse unterteilen und auch die zuletzt aufgetretenen Übermittlungsprobleme exportieren.

Wenn Sie später feststellen, dass Domain1 eine Komponente enthält, die auch für Domain2 gültig ist, können Sie eine generische Version davon in Shared extrahieren.

Wie Sie sagten, organisieren sich viele Frameworks nach technischen Domänen, und das habe ich jetzt verwendet, nur weil meine FW der Wahl dies einfacher macht. Aber mit ein wenig (oder viel) Elbow-Fett könnte ich die Include-Pfade umschreiben, um auch das Business Domain-Layout zu unterstützen.

Laas
quelle
Ich finde die Idee großartig, aber ich kann mir kein praktisches Beispiel vorstellen. Könnten Sie eine einfache, aber aufschlussreiche geben?
Florian Margaine
@FlorianMargaine - Ich gebe Ihnen ein reales Beispiel. Immobilien-Websites. Bei meinem letzten Job haben wir mehrere Immobilien-Websites an viele Kunden verkauft. Wir hatten eine zentrale Datenbank für alle über 50 Kunden. Jeder Back-End-Administrator verwendete einen gemeinsamen Satz von Modulen. Jede dem Kunden zugewandte Seite verwendete einzigartige Bilder und Navigation. Für jede Such- und Drilldown-Seite wurden gemeinsam genutzte Module verwendet, es sei denn, ein Kunde wünschte sich einmalige Funktionen. Für diese einmaligen Aufgaben haben wir den Code aufgeteilt und ihnen ein eigenes Modul gegeben. (Nachteil: Upgrades mussten in den üblichen Modulen durchgeführt und in den einmaligen Modulen dupliziert werden)
Michael Riley - AKA Gunny
8

Ich finde es aufschlussreich zu fragen: "Was werde ich eher regelmäßig hinzufügen, mehr Domänen oder mehr technische Abteilungen?" Was auch immer die Antwort ist, stellen Sie diese auf die oberste Ebene.

In den meisten Fällen verfestigt sich Ihre technische Architektur schneller als Ihre Domain. Das heißt, Sie sollten zuerst nach Domäne und dann nach Architekturkomponente organisieren. Der Grund dafür ist, dass Sie, wenn sich etwas in einer Domäne ändert, möglicherweise mehrere technische Komponenten in dieser Domäne hinzufügen oder ändern müssen, dies jedoch hoffentlich lokalisiert ist und nicht viel in andere Domänen übergeht.

Wenn Sie Ihr GUI-Framework geändert haben, bedeutet dies, dass sich Ihre Änderungen auf die gesamte Anwendung auswirken. Andererseits ändern Sie Ihr GUI-Framework selten, ändern jedoch immer Ihre Domänenlogik.

Halten Sie die Dinge zusammen, wenn sie sich wahrscheinlich gleichzeitig ändern.

Scott Whitlock
quelle
Bester Rat, aber ich verstehe nicht, wie ich vorhersagen kann, welche Art von Domains ich am häufigsten hinzufügen werde.
Florian Margaine
Der letzte Satz nagelt es.
Hakan Deryal
@FlorianMargaine - Ich denke nicht, dass die "Art" der Domain wichtig ist. Wenn Sie mehr Domains hinzufügen als neue technische "Dinge", gruppieren Sie alles zuerst nach Domains.
Scott Whitlock
3

Es gibt eine andere Alternative, die darin besteht, die einzelnen Teile in Plugins zu verschieben. CakePHP macht das zum Beispiel. Damit können Sie komplette MVC-Teile generieren, die wiederverwendbar sind und nach beliebiger Logik sortiert werden können.

Ihre Hauptanwendung wird sie nur verwenden und mit ihnen verknüpfen.

Grundsätzlich geht es bei Ihrer Frage auch um Zusammenhalt und Kopplung. Sie möchten, dass die einzelnen Teile so unabhängig wie möglich arbeiten. Auf diese Weise erhalten Sie testbaren und wiederverwendbaren Code.

Berücksichtigen Sie Folgendes: Wenn Sie sich nach Domänen aufteilen, wie würden Sie Teile Ihrer Anwendung wiederverwenden? Nehmen Sie zum Beispiel einen Webshop: Eine Anfrage für / orders / view / 1 geht ein, sodass Sie die Bestellnummer anzeigen müssen. 1. Ruft / orders / controller / order_controller auf. Wenn Sie die Domain nach Produkten und Bestellungen trennen, benötigen Sie bereits Teile der anderen "Domain".

Dort können Sie anfangen, Dinge miteinander zu verbinden, aber wahrscheinlich sind die Dinge in den meisten Geschäftsbereichen einfach zu zusammenhängend. Wenn Sie den technischen Ansatz wählen. Zum Beispiel könnten Sie ein Plugin haben, das Bestellungen bearbeitet. Sie fügen Product-Objekte aus Ihrer zentralen Anwendung hinzu. Auf diese Weise können Sie das Plugin einfach testen. Erstellen Sie einfach ein Produktobjekt mit einem Namen und einem Preis und senden Sie es ab.

Das Plugin wird genau das tun, was es tun muss. Dies hängt von der Eingabe ab und nicht von anderen "Teilen / Domänen / Bereichen".

Luc Franken
quelle
Gute Idee. Es ist im Wesentlichen von oben nach unten in meiner Antwort. Ich habe Shared Code an die erste Stelle gesetzt und im Grunde genommen die Domain-Details eingegeben. Sie setzen Domain an die Spitze und stecken Shared Code ein. Ich denke, beide sind gleichermaßen gute Ansätze in Bezug auf Entkopplung und Testbarkeit.
Laas
2

Microsoft ASP.Net MVC 3 hat das Konzept der "Bereiche". Wenn Sie "Areas" in Ihr MVC-Projekt einfügen, wird es folgendermaßen aufgeteilt:

area1/
   models
   views
   controllers
area2/
   models
   views
   controllers

Ich fand das ganz natürlich. Ein Bereich ist ein "großer Teil" eines Projekts, und die Arbeit in einer eigenständigen Einheit ergab einfach einen großen Sinn.

Wir haben Namespaces verwendet, um übereinzustimmen, FWIW.

gahooa
quelle
2
Vielen Dank für Ihren Beitrag, aber wie beantwortet das meine Frage? (Vergleich beider Lösungen)
Florian Margaine
@FlorianMargaine: Ich illustriere, wie Microsoft es gemacht hat, mit der (möglicherweise fehlerhaften) Annahme, dass sie viel technischen Aufwand in die vernünftigere Auswahl gesteckt haben. Hoffe, es gibt etwas Input.
Gahooa
Ok, aber so habe ich es in meiner Frage gezeigt ...
Florian Margaine
1

Aus meiner persönlichen Erfahrung mit einem Webshop, der aus 300.000 Codezeilen besteht, habe ich mich immer für die Organisation nach Geschäftsbereichen entschieden. Auf diese Weise erhalten Sie nicht nur einen schnellen Überblick über alle relevanten Klassen, wenn Sie an einem Funktionsbereich arbeiten, sondern können in Java auch die Paketsichtbarkeit nutzen.

Einige Details für Interessierte: Als das Projekt vor 5 Jahren gestartet wurde, haben die Entwickler die folgende Paketstruktur erstellt:

com
  example
    web
      struts
        action
        form
      shared
      functionality1
      functionality2

Jede Shop-Funktion wie Warenkorb, Produktsuche usw. besteht aus mehreren Aktionen mit jeweils einer eigenen Formularklasse (vom MVC-Framework vorgegebene Struktur). Am Ende befanden sich über 200 Klassen im Aktionspaket, von denen jede vollständig von der zugehörigen Formularklasse getrennt ist. Schlimmer ist, dass Aktionen nicht zu viel Logik implementieren, sondern funktionsspezifische Services aufrufen, die sich in einem weiteren Paket befinden.

Ich schlug dem Team vor und überzeugte es, dass wir auf die Organisation von Paketen nach Geschäftsbereichen umstellen sollten. Die Argumentation ist einfach: Wenn Sie wirklich eine Liste aller Aktionen anzeigen möchten, können Sie einfach die Typhierarchie-Ansicht einer anständigen IDE öffnen. Die IDE kann jedoch nicht auf die Geschäftsdomäne schließen, zu der eine Klasse gehört. Darüber hinaus können Sie mit diesem Ansatz nur die Klassen öffentlich machen, die von mehreren Funktionen benötigt werden, während der Rest für die Paketsichtbarkeit bleibt.

Jens Bannmann
quelle
0

Ich bin damit einverstanden, dass sich viele Frameworks nach technischen Domänen trennen, und beginne daher häufig so, wenn ich ein neues Framework verwende. Ich entscheide mich jedoch konsequent dafür, die Unternehmensdomäne als primäre Ebene der Ordnerorganisation zu verwenden.

Persönlich denke ich, dass es viel einfacher ist, meinen Foo-Controller und das Foo-Repository oder was auch immer zusammen zu halten, als zwischen dem Ordner des Controllers und dem Ordner des Repositorys hin und her zu wechseln, da ich beim Hinzufügen von Funktionen um Foo häufig an beiden arbeiten muss. Bei größeren Projekten ist dies umso wichtiger, als der Abstand zwischen technischen Ordnern groß sein und während der Entwicklung zu einer spürbaren Zeitverschwendung führen kann.

Quentin-Starin
quelle