web-dev-qa-db-fra.com

Existe-t-il des meilleures pratiques pour l'organisation de packages (Java)?

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.

185
Cyntech

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:

  • Suivez Java conventions de dénomination des paquets
  • Structurez vos packages en fonction de leur rôle fonctionnel et de leur rôle commercial
    • Décomposez vos packages en fonction de leurs fonctionnalités ou de leurs modules. par exemple. com.company.product.modulea
    • Une autre panne pourrait être basée sur les couches de votre logiciel. Mais n'allez pas trop loin si vous n'avez que quelques classes dans le paquet, il est donc logique de tout avoir dans le paquet. par exemple. com.company.product.module.web ou com.company.product.module.util etc.
    • Évitez de trop vous structurer, IMO évitez les emballages séparés pour les exceptions, les usines, etc. sauf si cela est urgent.
  • Si votre projet est petit, restez simple avec quelques paquets. par exemple. com.company.product.model et com.company.product.util, etc.
  • Jetez un coup d'oeil à quelques-uns des projets open source populaires qui existent sur projets Apache . Voyez comment ils utilisent la structuration pour des projets de différentes tailles.
  • Pensez également à la construction et à la distribution lors de l'attribution de nom (vous permettant de distribuer votre api ou votre SDK dans un paquet différent, voir api de servlet).

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.

158
naikus

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.

155
onof

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

38
Peter Tseng

Je préfère les fonctionnalités avant les couches, mais je suppose que cela dépend de votre projet. Considérez vos forces:

  • dépendances
    Essayez de réduire les dépendances entre les paquets, en particulier entre les fonctionnalités. Extraire les API si nécessaire.
  • Organisation de l'équipe
    Dans certaines organisations, les équipes travaillent sur des fonctionnalités et d’autres sur des calques. Cela influence l’organisation du code, l’utilise pour formaliser les API ou encourage la coopération.
  • Déploiement et versioning
    Tout mettre dans un module simplifie le déploiement et la gestion des versions, mais il est plus difficile de corriger les bogues. Le fractionnement permet un meilleur contrôle, une évolutivité et une disponibilité accrues.
  • Répondre au changement
    Un code bien organisé est beaucoup plus simple à modifier qu’une grosse boule de boue.
  • Taille (personnes et lignes de code)
    Plus il est important, plus il doit être formalisé/normalisé.
  • Importance/qualité
    Certains codes sont plus importants que d’autres. Les API devraient être plus stables que l'implémentation. Par conséquent, il doit être clairement séparé.
  • Niveau d'abstraction et point d'entrée
    Il devrait être possible à un tiers de savoir en quoi consiste le code et par où commencer à lire en regardant dans l’arbre des paquets.

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.

14
ThomasGran

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 ".

11
Stephen C

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é":

  • Favorise la création de frameworks réutilisables (bibliothèques avec les aspects modèle et interface utilisateur)
  • Permet l'implémentation de couche plug and play - pratiquement impossible avec 'package by feature' car elle place l'implémentation de couche dans le même package/répertoire que le code du modèle.
  • Beaucoup plus...

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.

6
Volksman

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.

3
Brian S