Java-Anwendungsstruktur: Horizontale vs. vertikale Aufteilung

15

Eine kleine Debatte über den Start der Projektstruktur (unter Verwendung von Maven / Eclipse) für eine große Java-Anwendung.

Option 1:

entities (i.e. the whole database using Hibernate classes-first)
services (i.e. sets of read/write operations on the entities)
app (perhaps split up more further down the line)

Option 2:

area1-entities
area1-services
area1-app
area2-entities
area2-services
area2-app
...
(where area1, area2 etc. are functional areas of the system)

Option 2 wird deutlich mehr Maven-Projekte / -Module zur Folge haben und bedeutet, dass die Klassen, die die Datenbank generieren würden, auf mehrere Projekte verteilt sind. Könnte jemand für / gegen jeden Ansatz raten?

Steve Chambers
quelle
3
Weder. IMHO (los geht's) sollten wir damit aufhören, uns von technischen Schichten zu trennen, was einfach zu einem großen Schlammballen führt. Stattdessen funktional verpacken. Nur area1 / area2, das den Kern Ihrer Anwendung enthalten sollte (Entities, Services (aufgeteilt in öffentliche Schnittstelle und Paket-Private-Implementation), Repositorys (falls erforderlich). Nun sollten Sie Ihre web / ws / messaging-Schicht mit diesem Kern verbinden. Möglicherweise
Es ist immer noch opiniert :). Aber ich werde ein bisschen nacharbeiten, um eine Antwort zu finden.
Vielen Dank, aber diese Frage bezieht sich eher auf die Projektstruktur als auf die Paketstruktur
Steve Chambers

Antworten:

28

Ich würde vorschlagen, beides nicht zu tun.

Der Versuch, eine technische Schichtung mit einer Paketstruktur zu erzwingen, führt zu einer starken Verstrickung in Ihrer Anwendung. Ganz zu schweigen von der Tatsache, dass wir uns so sehr bemühen, alles hinter einer Serviceschnittstelle zu verbergen, und das erste, was wir (hauptsächlich aufgrund der Verpackung) tun, ist, alles zu einem Guten zu machen public class. Dies wird schmerzhaft, wenn es eine technische Trennung zwischen a x.y.z.serviceund x.y.z.repositorypackage gibt, jetzt kann alles auf das Repository zugreifen. Boom dort geht Ihre Einkapselung innerhalb der Service-Schicht.

Stattdessen sollten Sie einen funktionaleren und zwiebelbasierten Ansatz verfolgen ( saubere Architektur , hexagonale Architektur ). Dies steht auch im Einklang mit dem Grundsatz der einheitlichen Verantwortung (wenn es auf ein Paket angewendet wird) und auch mit den Verpackungsgrundsätzen

  1. Dinge, die sich gemeinsam ändern, werden zusammen verpackt
  2. Dinge, die zusammen verwendet werden, werden zusammen verpackt

Oliver Gierke hat einen schönen Beitrag über das gemeinsame Verpacken von Komponenten in Java geschrieben. Simon Brown hat eine allgemeinere Geschichte zu diesem Thema geschrieben.

Ich würde eine Kernpaketstruktur wie die folgende anstreben, um den Kern Ihrer Anwendung zu halten:

x.y.z.area1
x.y.z.area2

Wenn Sie nun eine Webschnittstelle haben, fügen Sie beispielsweise ein webUnterpaket hinzu, damit der Webservice a wsoder das restPaket nur das enthält. Es verbindet sich im Grunde mit dem Kern.

x.y.z.area1.web
x.y.z.area1.ws
x.y.z.area2.rest

Jetzt könnten Sie die Objekte aus Ihrem Kern in die anderen Ebenen wiederverwenden, aber IMHO ist es besser, eine bestimmte Domäne für diese Ebene zu verwenden. Ebenso wie bei der Objekt-zu-SQL-Zuordnung gibt es (oft) Unstimmigkeiten bei der Anzeige auf dem Bildschirm oder der Verwendung als XML im Webservice und bei der Implementierung der Geschäftslogik. Abhängig von der Komplexität der Geschäfts- und Webdomänen können Sie diese als separate zu lösende Problemdomänen betrachten, die miteinander verbunden werden müssen, im Grunde genommen zwei verschiedene begrenzte Kontexte .

So verwenden Sie ein Zitat aus einer CQRS-Ressource

Es ist nicht möglich, eine optimale Lösung für die Suche, Berichterstellung und Verarbeitung von Transaktionen mithilfe eines einzelnen Modells zu erstellen.

Versuchen Sie nicht, alles in ein einziges (Domain-) Modell zu packen, sondern trennen Sie die Verantwortlichkeiten. Sie haben wahrscheinlich mehr (kleinere) Klassen, aber eine sauberere Trennung zwischen den Ebenen Ihrer Anwendung.

Schlussbemerkung

Denken Sie daran, dass das Erstellen einer Architektur über die Kompromisse zwischen den Lösungen entscheidet. Dies hängt stark von der Komplexität der Domäne ab und sollte hauptsächlich von den funktionalen Anforderungen Ihrer Anwendung abhängen. Es wird jedoch durch die nicht funktionalen (Leistung, Sicherheit) und umgebungsbedingten Einschränkungen (zu verwendende Sprache, Plattform, Erfahrung) beeinflusst. Und Architektur, wie das Codieren, ist nie abgeschlossen. Jede neue Anforderung kann (und sollte?) Zu einer Neugestaltung der Anwendung führen.

Haftungsausschluss

Ja, ich habe auch versucht, alles in ein einziges Modell zu packen, und ich habe auch versucht, eine technische Trennung in meinen Anwendungen zu verwenden. Nach ein paar Jahren Erfahrung in der Erstellung von verschränkten Anwendungsschichten (zunächst scheint es eine gute Idee zu sein, dann wächst die Anwendung ...), dachte ich, dass es einen anderen Weg geben muss.

Links

  1. Saubere Architektur, Onkel Bob Martin
  2. Sechseckige Architektur (auch bekannt als Ports und Adapter), Alistair Cockburn
  3. Whoops wo ist meine Architektur geblieben, Oliver Gierke
  4. Grundsätze der OOD, Onkel Bob Martin
  5. Fehler beim Anwenden von DDD, Udi Dahan
  6. Gebundene Kontexte, Martin Fowler
  7. Architectural Evident Coding Style, Simon Brown

Bücher

  1. Wachsende objektorientierte Software, basierend auf Tests
  2. Java-Anwendungsarchitektur: Modularitätsmuster mit Beispielen unter Verwendung von OSGi (Robert C. Martin Series)
  3. Domain-Driven Design: Komplexität im Herzen von Software bewältigen
  4. Softwarearchitektur für Entwickler
  5. Implementieren von Domain Driven Design
M. Deinum
quelle
1
Nette Antwort :) Ich würde ein Must-Read hinzufügen, um dieses Thema anzugehen: amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/…
Mik378
1
Gut, fügte meiner ursprünglichen Antwort noch ein paar hinzu.
1
Es ist mit Abstand das beste Buch über Design, das ich gelesen habe;) Sie können das Buch von Vaughn Vernon erwähnen, das auch sehr gut ist: amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/…
Mik378
@ M.Deinum +1 Gut als Referenz!
1
@ Mik378 Ich habe beide Bücher in meiner, digitalen, Bibliothek unter vielen anderen.