Comment dois-je structurer une application Java, où dois-je placer mes classes?
Tout d'abord, je sais comment construire une application Java. Mais j'ai toujours été perplexe sur où mettre mes classes. Il y a des partisans de l'organisation de la les paquets dans un domaine strictement orientée vers la mode, d'autres séparés par niveau.
J'ai moi-même toujours eu des problèmes avec
- de nommage,
- placer
Donc,
- Où mettez-vous votre domaine spécifique des constantes (et quel est le meilleur nom pour une classe)?
- Où avez-vous mis des classes pour des choses qui sont à la fois des infrastructures et spécifique au domaine (par exemple, j'ai un FileStorageStrategy classe, qui stocke les fichiers dans la base de données, ou bien dans la base de données)?
- Où mettre Exceptions?
- Sont il des normes à qui je peux consulter?
- Il n'y a évidemment pas de réponse définitive, mais après l'utilisation de maven2 pendant un certain temps je suis venu à appriciate la structure donnée, et par conséquent, je déclare le maven réponse comme celle-ci. (Cela ne signifie pas que les autres sont mauvais, ou quoi que ce soit) je viens de réaliser combien il est plus facile de ne pas avoir à réfléchir sur les premières étapes de votre construction, vous déposez simplement vos sources et reources dans celles données des répertoires et ça compile sans créer de fichiers ant et d'autres choses.
Vous devez vous connecter pour publier un commentaire.
J'ai vraiment comme Maven est Répertoire Standard De Mise En Page.
L'une des principales idées qui pour moi est d'avoir deux racines, l'une pour la production de code et un code de test comme suit:
(ici, à la fois src/main/java et src/test/java sont source de racines).
Avantages:
Une règle de base à propos de la classe de placement et des paquets:
Généralement parlant, bien structuré projets seront libres de les dépendances circulaires. Apprendre quand ils sont mauvais (et quand ils sont pas), et d'envisager un outil comme JDepend ou SonarJ qui vous aidera à éliminer.
Je suis un grand fan de organisé sources, j'ai donc toujours créer la structure de répertoire suivante:
Dans /src, je suis en utilisant le Java par défaut de motifs: les noms de paquets de départ avec votre nom de domaine (org.votredomaine.yourprojectname) et la classe des noms reflétant la POO aspect vous êtes en train de créer avec la classe (voir les autres intervenants). Package commun des noms comme util, modèle, vue, événements sont utiles, aussi.
J'ai tendance à mettre des constantes pour un sujet spécifique dans une catégorie à part, comme SessionConstants ou ServiceConstants dans le même package des classes du domaine.
Où je travaille, nous sommes à l'aide de Maven 2 et nous avons une assez bonne archétype de nos projets. Le but était d'obtenir une bonne séparation des préoccupations, ainsi nous avons défini une structure de projet à l'aide de plusieurs modules (un pour chaque application "couche"):
- commune: commune code utilisé par les autres couches (par exemple, i18n)
- entités: les entités de domaine
- référentiels: ce module contient les daos les interfaces et implémentations
- services-intf: les interfaces pour les services d'e.g, UserService, ...)
- services-impl: les implémentations de services (à l'e.g, UserServiceImpl)
- web: tout ce qui concerne le contenu web (par exemple, css, jsp, jsf, pages, ...)
- ws: services web
Chaque module possède ses propres dépendances (par exemple, ils pourraient avoir jpa) et du projet (ainsi qu'ils appartiennent à la commune de module). Les dépendances entre les différents modules de projets clairement la part des choses (par exemple, le calque web dépend de la couche de service, mais ne savez pas au sujet de dépôt de la couche).
Chaque module dispose de son propre module de base, par exemple, si le dossier de demande est "com.foo.bar", alors nous avons:
Chaque module respecte le projet maven standard structure:
De tests unitaires pour une couche donnée facilement trouver leur place sous \src\test... Tout ce qui est spécifique au domaine a sa place dans les entités du module. Maintenant, quelque chose comme un FileStorageStrategy devrait aller dans les référentiels de module, puisque nous n'avons pas besoin de savoir exactement ce que la mise en œuvre est. Dans la couche de services, nous ne connaissons que le référentiel de l'interface, nous ne nous soucions pas de ce que la mise en œuvre spécifique est (séparation des préoccupations).
Il y a plusieurs avantages à cette approche:
Je sais que ce n'est pas de répondre à toutes vos questions, mais je pense que cela pourrait vous mettre sur la bonne voie et pourrait s'avérer utile à d'autres.
Les noms de classe doivent toujours être descriptifs et explicatifs. Si vous avez de multiples domaines de la responsabilité de vos classes alors qu'ils devraient probablement être remaniée.
De même pour vous des forfaits. Ils doivent être regroupées par domaine de responsabilité. Chaque domaine a ses propres exceptions.
Généralement pas de panique jusqu'à ce que vous arrivez à un point où il devient écrasante et de ballonnement. Puis asseyez-vous et n'avez pas de code, juste refactoriser les classes, de compiler régulièrement pour s'assurer que tout fonctionne. Ensuite, continuez comme vous l'avez fait avant.
Utiliser les paquets de groupe fonctionnalités liées ensemble.
Généralement le haut de votre arbre est votre nom de domaine inversé (
com.domain.subdomain
) pour garantir l'unicité, puis, généralement, il y aura un package de votre application. Ensuite subdiviser que, par ailleurs, de sorte que votreFileStorageStrategy
peut aller, dire,com.domain.subdomain.myapp.storage
, et alors il pourrait y avoir des implémentations spécifiques/sous-classes/que ce soit danscom.domain.subdomain.myapp.storage.file
etcom.domain.subdomain.myapp.storage.database
. Ces noms peuvent être assez long, maisimport
les tient tous en haut de fichiers et IDEs peuvent aider à gérer cela.Exceptions vont généralement dans le même package que les classes que de les jeter, donc si vous avait, disons,
FileStorageException
il serait aller dans le même package queFileStorageStrategy
. De même, une interface qui définit les constantes serait dans le même package.Il n'est pas vraiment une norme en tant que telle, il suffit d'utiliser le sens commun, et si tout devient trop sale, refactoriser!
Une chose que j'ai trouvé très utile pour les tests unitaires était d'avoir un myApp/src/et aussi myApp/test_src/répertoires. De cette façon, je peux en place des tests unitaires dans le même boîtier que les classes à tester, et pourtant, je peux facilement exclure les cas de test quand je prépare mon installation de production.
Réponse courte: dessiner votre architecture du système en termes de modules, tiré côté-à-côte, avec chaque module découpée verticalement en couches (par exemple, la vue, le modèle, la persistance). Puis utiliser une structure comme com.mycompany.myapp.somemodule.somelayer, par exemple com.mycompany.myapp.client.vue ou com.mycompany.myapp.serveur.modèle.
En utilisant le haut niveau de packages pour l'application modules, dans la old-fashioned de l'informatique sens de la programmation modulaire, devrait être évident. Cependant, sur la plupart des projets, j'ai travaillé sur on finit par oublier de le faire, et se retrouver avec un désordre de paquets, sans que la structure de premier niveau. Cet anti-modèle montre généralement lui-même comme un paquet pour quelque chose comme "auditeurs" ou "actions" que les groupes des classes non connexes simplement parce qu'elles implémentent la même interface.
À l'intérieur d'un module, ou dans une petite application, de l'utilisation des packages pour l'application de couches. Probablement forfaits comprennent des choses comme les suivantes, en fonction de l'architecture:
À l'intérieur de chacune de ces couches, il est naturel pour des cours de groupe par type si il y en a beaucoup. D'un commun anti-modèle ici est d'introduire inutilement trop de paquets et les niveaux de sous-paquet, de sorte qu'il y a seulement quelques classes dans chaque paquet.
Je pense rester simple et ne pas trop penser à elle. Ne pas trop abstrait et de la couche de trop. Il suffit de le garder propre et à mesure qu'il grandit, le refactoring, c'est trivial. Une des meilleures caractéristiques de IDEs est refactoring, alors pourquoi ne pas l'utiliser et de vous sauver la puissance du cerveau pour résoudre les problèmes qui sont liés à votre application, plutôt que de méta questions comme le code de l'organisation.
Une chose que j'ai fait dans le passé - si je suis à l'extension d'une classe, je vais essayer et suivre leurs conventions. Par exemple, lorsque l'on travaille avec le Framework Spring, je vais avoir mon MVC Contrôleur de classes dans un package nommé com.mydomain.myapp.web.servlet.mvc
Si je ne suis pas l'extension de quelque chose, j'ai juste aller avec ce qui est le plus simple. com.mydomain.de domaine pour le Domaine des Objets (bien que si vous avez une tonne d'objets de domaine de ce paquet pourrait obtenir un peu lourd).
Pour le domaine spécifique des constantes, j'ai, en fait comme des constantes publiques dans la plupart des classes. Par exemple, si j'ai un "Membre" de la classe et d'avoir un maximum de membre nom de la constante de longueur, je l'ai mis dans le Membre de classe. Certains magasins en faire un distinct des Constantes de la classe, mais je ne vois pas la valeur dans la formation de grumeaux sans rapport avec les nombres et les chaînes de caractères en une seule classe. J'ai vu quelques autres magasins d'essayer de résoudre ce problème par la création de SÉPARER les Constantes de classes, mais qui semble juste comme une perte de temps et le résultat est trop confus. En utilisant cette configuration, un grand projet avec plusieurs développeurs sera la duplication des constantes de tous sur la place.
J'aime me casser les classes de bas en paquets qui sont liés les uns aux autres.
Par exemple:
Modèle Pour la base de données des appels liés à la
Vue Classes qui traitent de ce que vous voyez
Contrôle fonctionnalités de Base des classes
Util Tout misc. les classes qui sont utilisées (généralement des fonctions statiques)
etc.