Il y a quelques instants, j'ai trouvé ici une réponse à une question concernant l'organisation détaillée des packages Java. Par exemple, my.project.util
, my.project.factory
, my.project.service
, etc.
Je ne le trouve pas maintenant, alors je peux aussi bien poser la question.
Existe-t-il des meilleures pratiques en ce qui concerne l'organisation des packages dans Java et leur contenu?
Comment organisez-vous vos classes dans votre projet Java?
Par exemple, un projet sur lequel je travaille avec quelques personnes contient un paquet appelé haricots. Il a commencé par être un projet contenant de simples haricots, mais il a fini par tout (presque). Je les ai un peu nettoyées, en plaçant certaines classes factory dans un package factory (classes avec des méthodes statiques qui créent des beans), mais nous avons d'autres classes qui font de la logique métier et d'autres qui effectuent un traitement simple (pas avec la logique métier), comme l'extraction un message pour un code d'un fichier de propriétés.
Vos idées et commentaires sont appréciés.
L'organisation ou la structuration des paquets est généralement une discussion animée. Vous trouverez ci-dessous quelques instructions simples pour nommer et structurer les packages:
com.company.product.modulea
com.company.product.module.web
ou com.company.product.module.util
etc.com.company.product.model
et com.company.product.util
, etc.Après quelques expériences et essais, vous devriez pouvoir proposer une structure avec laquelle vous êtes à l'aise. Ne soyez pas concentré sur une convention, soyez ouvert aux changements.
J'organise les packages par fonctionnalité, et non par modèles ou rôles d'implémentation. Je pense que des paquets comme:
beans
factories
collections
sont faux.
Je préfère par exemple:
orders
store
reports
je peux donc masquer les détails de la mise en œuvre grâce à visibilité du paquet . Les commandes d'usine doivent figurer dans le package orders
afin que les détails relatifs à la création d'une commande soient masqués.
Réponse courte: Un package par module/fonctionnalité, éventuellement avec des sous-packages. Mettez les choses étroitement liées ensemble dans le même paquet. Évitez les dépendances circulaires entre les paquets.
Réponse longue: Je suis d'accord avec la plupart de cet article
Je préfère les fonctionnalités avant les couches, mais je suppose que cela dépend de votre projet. Considérez vos forces:
Exemple:
com/company/module
+ feature1/
- MainClass // The entry point for exploring
+ api/ // Public interface, used by other features
+ domain/
- AggregateRoot
+ api/ // Internal API, complements the public, used by web
+ impl/
+ persistence/
+ web/ // presentation layer
+ services/ // Rest or other remote API
+ support/
+ feature2/
+ support/ // Any support or utils used by more than on feature
+ io
+ config
+ persistence
+ web
C'est juste un exemple. C'est assez formel. Par exemple, il définit 2 interfaces pour feature1 . Normalement, ce n'est pas obligatoire, mais cela pourrait être une bonne idée si utilisé différemment par différentes personnes. Vous pouvez laisser l'API interne étendre le public.
Je n'aime pas les noms 'impl' ou 'support', mais ils permettent de séparer les éléments moins importants des éléments importants (domaine et API). Quand il s'agit de nommer, j'aime être aussi concret que possible. Si vous avez un paquet appelé 'utils' avec 20 classes, déplacez StringUtils
vers support/string, HttpUtil
vers support/http et ainsi de suite.
Existe-t-il des meilleures pratiques en ce qui concerne l'organisation des packages dans Java et leur contenu?
Non, pas vraiment. Il y a beaucoup d'idées et d'opinions, mais la "bonne pratique" consiste à utiliser votre bon sens!
Cependant, il existe un principe qui a probablement une large acceptation. Votre structure de package doit refléter la structure de module (informelle) de votre application, et vous devez vous efforcer de minimiser (ou idéalement d'éviter entièrement) les dépendances cycliques entre les modules.
(Les dépendances cycliques entre les classes d’un package/module sont très bien, mais les cycles inter-packages ont tendance à rendre difficile la compréhension de l’architecture de votre application et peuvent constituer un obstacle à la réutilisation du code. les dépendances inter-paquet/inter-module signifient que tout le désordre interconnecté doit être un artefact Maven.)
Je devrais également ajouter qu’il existe une pratique exemplaire largement acceptée pour les noms de paquets. Et c’est que les noms de vos paquets doivent commencer par le nom de domaine de votre organisation dans l’ordre inverse. Si vous suivez cette règle, vous réduirez les risques de conflits entre vos noms de classe (complets) et d'autres peuples ".
J'ai vu certaines personnes promouvoir "paquet par fonctionnalité" plutôt que "paquet par couche", mais j'ai utilisé plusieurs approches au cours de nombreuses années et trouvé "paquet par couche" bien meilleur que "paquet par fonctionnalité".
De plus, j'ai constaté qu'une stratégie hybride: "paquet par module, couche puis fonctionnalité" fonctionne extrêmement bien dans la pratique, car elle présente de nombreux avantages du "paquet par fonctionnalité":
J'explique en détail ici: Structure et organisation du nom du paquet Java mais ma structure de paquet standard est la suivante:
revdomain.moduleType.moduleName.layer. [layerImpl] .feature.subfeatureN.subfeatureN + 1 ...
Où:
revdomain Domaine inverse, par exemple. com.mycompany
moduleType [app * | framework | util]
moduleName par exemple. myAppName si le type de module est une application ou 'finance' s'il s'agit d'un cadre comptable
couche [modèle | ui | persistance | sécurité etc.,]
layerImpl Par exemple, un guichet, jsp, jpa, jdo, hibernate (Remarque: non utilisé si la couche est un modèle).
caractéristique par exemple, finance
subfeatureN p.ex. comptabilité
subfeatureN + 1 Par exemple, amortissement
* Parfois, 'app' est omis si moduleType est une application, mais sa mise en place rend la structure du package cohérente pour tous les types de modules.
Je ne suis pas au courant des pratiques standard pour l'organisation de paquets. Je crée généralement des packages qui couvrent un spectre assez large, mais je peux faire la différence au sein d'un projet. Par exemple, un projet personnel sur lequel je travaille actuellement comporte un package dédié à mes contrôles d'interface utilisateur personnalisés (pleins de classes de sous-classes de swing). J'ai un paquet consacré à la gestion de ma base de données, un paquet pour un ensemble d'auditeurs/événements que j'ai créés, etc.
D'autre part, un collègue a créé un nouveau package pour presque tout ce qu'il a fait. Chaque MVC différent qu'il souhaitait avait son propre paquet, et il semblait qu'un ensemble de MVC était le seul groupe de classes autorisé à être dans le même paquet. Je me souviens qu'à un moment donné, il avait 5 packages différents qui comportaient chacun une seule classe. Je pense que sa méthode est un peu à l'extrême (et l'équipe l'a forcé à réduire le nombre de ses paquets quand nous ne pouvions tout simplement pas le gérer), mais pour une application non triviale, il serait tout aussi judicieux de tout mettre dans le même paquet. C'est un point d'équilibre que vous et vos coéquipiers devez trouver vous-même.
Une chose que vous pouvez faire est d’essayer de prendre du recul et de réfléchir: si vous étiez un nouveau membre introduit dans le projet, ou si votre projet était publié en open source ou en tant qu’API, serait-il facile de trouver ce que vous voulez? Parce que pour moi, c'est ce que je veux vraiment dans les paquets: l'organisation. Semblable à la façon dont je stocke les fichiers dans un dossier sur mon ordinateur, je m'attends à pouvoir les retrouver sans avoir à chercher dans tout mon lecteur. J'espère pouvoir trouver la classe que je veux sans avoir à chercher dans la liste de toutes les classes du paquet.