Structure d'application Java: séparation horizontale vs verticale

15

Avoir un peu de débat sur la structure de démarrage du projet (en utilisant Maven / Eclipse) pour une grande application Java.

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)

L'option 2 entraînera clairement beaucoup plus de projets / modules Maven et signifie que les classes qui généreraient la base de données sont réparties entre plusieurs projets. Quelqu'un pourrait-il conseiller les avantages / inconvénients de chaque approche?

Steve Chambers
la source
3
Ni. À mon humble avis (nous y voilà), nous devrions arrêter de séparer les couches techniques qui conduisent simplement à une grosse boule de boue. Au lieu de cela, empaquetez fonctionnellement. Juste zone1 / zone2 qui devrait contenir le cœur de votre application (entités, services (divisés en interface publique et implémentation privée de package), référentiels (si nécessaire). Maintenant, vous devez connecter votre couche web / ws / messagerie à ce cœur. Vous pourriez voulez jeter un œil ici et ici
Il est toujours d'opinion :). Mais je vais faire un peu de polissage pour le mettre dans une réponse.
Vous voudrez peut-être consulter stackoverflow.com/questions/11733267/…
Merci, mais cette question concerne la structure du projet plutôt que la structure du package
Steve Chambers

Réponses:

29

Je suggérerais de ne faire ni l'un ni l'autre.

Essayer d'imposer une superposition technique avec une structure de package entraîne de nombreux enchevêtrements dans votre application. Sans parler du fait que nous nous efforçons de tout cacher derrière une interface de service et la première chose que nous faisons (principalement en raison de l'emballage) est de tout faire a public class. Cela devient pénible lorsqu'il y a une séparation technique entre un x.y.z.serviceet un x.y.z.repositorypackage, maintenant tout peut accéder au référentiel. Boom là va votre encapsulation à l'intérieur de la couche de service.

Au lieu de cela , vous devez suivre une approche plus fonctionnelle et l' oignon ( l' architecture propre , l' architecture hexagonale ). Ceci est également parfaitement conforme au principe de responsabilité unique (lorsqu'il est appliqué à un emballage) et également conforme aux principes d'emballage.

  1. Les choses qui changent ensemble sont emballées ensemble
  2. Les choses qui sont utilisées ensemble sont emballées ensemble

Oliver Gierke a écrit un bel article sur le regroupement des composants en Java. Simon Brown a écrit une histoire plus générale sur le sujet.

Je m'efforcerais d'avoir une structure de package de base comme la suivante pour contenir le cœur de votre application:

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

Maintenant, si vous avez une interface Web, vous ajoutez, par exemple, un sous- webpackage, pour que le service Web wsou le restpackage contienne uniquement cela. Il se connecte essentiellement au noyau.

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

Vous pouvez maintenant envisager de réutiliser les objets de l'intérieur de votre noyau dans les autres couches, mais à mon humble avis, il est préférable d'utiliser un domaine spécifique pour cette couche. Comme, tout comme avec le mappage objet à SQL, il y a (souvent) un décalage dans ce que nous voulons afficher à l'écran ou utiliser comme XML dans le service Web et comment la logique métier est implémentée. En fonction de la complexité des domaines commerciaux et Web, vous pouvez les considérer comme des domaines de problèmes distincts à résoudre, qui doivent être connectés, essentiellement 2 contextes bornés différents .

Pour utiliser un devis d'une ressource CQRS

Il n'est pas possible de créer une solution optimale pour la recherche, la génération de rapports et le traitement des transactions à l'aide d'un modèle unique.

N'essayez pas de tout mettre dans un seul modèle (domaine), séparez les responsabilités. Vous vous retrouvez probablement avec plus de classes (plus petites) mais une séparation plus nette entre les couches de votre application.

Note finale

N'oubliez pas que créer une architecture, c'est décider des compromis d'une solution à l'autre. Il dépend fortement de la complexité du domaine et doit principalement être déterminé par les exigences fonctionnelles de votre application. Il est cependant influencé par les contraintes non fonctionnelles (performances, sécurité) et environnementales (langage à utiliser, plateforme, expérience). Et l'architecture, comme le codage, n'est jamais terminée, chaque nouvelle exigence peut (et peut-être devrait?) Conduire à une refonte de l'application.

Avertissement

Oui j'ai aussi essayé de tout mettre dans un seul modèle, et oui j'ai aussi essayé d'utiliser une séparation technique dans mes applications. Cependant, après quelques années d'expérience dans la création de couches d'application enchevêtrées (au début, cela semble une bonne idée, puis l'application commence à se développer ...) J'ai pensé qu'il devait y avoir une autre façon.

Liens

  1. Architecture propre, oncle Bob Martin
  2. Architecture hexagonale (alias ports et adaptateurs), Alistair Cockburn
  3. Oups où est passée mon architecture, Oliver Gierke
  4. Principes d'OOD, oncle Bob Martin
  5. Erreurs lors de l'application de DDD, Udi Dahan
  6. Contextes limités, Martin Fowler
  7. Style de codage architecturalement évident, Simon Brown

Livres

  1. Développement d'un logiciel orienté objet, guidé par des tests
  2. Architecture d'application Java: modèles de modularité avec exemples utilisant OSGi (série Robert C. Martin)
  3. Conception pilotée par domaine: s'attaquer à la complexité au cœur des logiciels
  4. Architecture logicielle pour les développeurs
  5. Implémentation d'une conception pilotée par domaine
M. Deinum
la source
1
Belle réponse :) J'ajouterais une lecture incontournable pour aborder ce sujet: amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/…
Mik378
1
Bon, j'en ai ajouté quelques autres à ma réponse originale.
1
C'est de loin le meilleur livre sur le design que j'ai lu;) Vous pouvez mentionner le livre Vaughn Vernon, très bon aussi: amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/…
Mik378
@ M.Deinum +1 Idéal pour référence!
1
@ Mik378 J'ai les deux livres dans ma bibliothèque numérique parmi tant d'autres.