web-dev-qa-db-fra.com

La structure de projet Java expliquée aux débutants?

Je viens d'un environnement .NET et je suis complètement nouveau en Java et j'essaie de comprendre la structure du projet Java. 

Ma structure de solution .NET typique contient des projets qui désignent des composants logiquement distincts, généralement nommés au format suivant: 

MyCompany.SomeApplication.ProjectName

Le nom du projet est généralement égal à l'espace de noms racine du projet. Je pourrais peut-être décomposer davantage l'espace de noms s'il s'agit d'un projet volumineux, mais le plus souvent, je ne vois pas le besoin de créer davantage d'espace de noms. 

Désormais, en Java, vous avez des applications composées de projets, puis vous avez un nouveau niveau logique - le package. Qu'est ce qu'un package? Que devrait-il contenir? Comment faites-vous un espace de noms dans cette structure App.Project.Package? Où se situent les JAR dans tout cela? Fondamentalement, quelqu'un peut-il fournir une introduction aux débutants dans la structure de l'application Java?

Merci!

Edit: Certaines réponses vraiment craquantes merci les gars. Quelques questions de suivi ensuite:

  • Les fichiers .JAR contiennent-ils du code compilé? Ou simplement des fichiers de code source compressés?
  • Y a-t-il une bonne raison pour laquelle les noms de paquetages sont tous en minuscules?
  • Les packages peuvent-ils avoir des 'dépendances circulaires'? En d'autres termes, Package.A peut-il utiliser Package.B et vice versa? 
  • Quelqu'un peut-il simplement montrer la syntaxe typique pour déclarer une classe comme étant dans un package et indiquant que vous souhaitez référencer un autre package dans une classe (une instruction using peut-être?)
45
MalcomTucker

"Simple" projets J2SE

Comme l'explique Cletus, la structure du répertoire source est directement équivalente à la structure du package, et elle est essentiellement intégrée à Java. Tout le reste est un peu moins clair.

Beaucoup de projets simples sont organisés à la main, afin que les gens puissent choisir une structure avec laquelle ils se sentent bien. Ce qui est souvent fait (et cela se reflète également dans la structure des projets dans Eclipse, un outil Java très dominant) consiste à faire en sorte que votre arborescence source commence dans un répertoire appelé src. Vos fichiers source sans paquet se trouveraient directement dans src, et votre hiérarchie de paquet, commençant généralement par un répertoire com, serait également contenue dans src. Si vous CD dans le répertoire src avant de lancer le compilateur javac, vos fichiers .class compilés se retrouveront dans la même structure de répertoires, chaque fichier .class se trouvant dans le même répertoire et à côté de son fichier .Java.

Si vous avez beaucoup de fichiers source et de classe, vous devrez les séparer les uns des autres pour réduire l'encombrement. Manual et Eclipse organisent souvent un répertoire bin ou classes parallèle à src pour que les fichiers .class se retrouvent dans une hiérarchie qui reflète celle de src.

Si votre projet comporte un ensemble de fichiers .jar à intégrer dans des bibliothèques tierces, un troisième répertoire, généralement lib, est placé parallèlement à src et bin. Tout dans lib doit être mis sur le chemin de classe pour la compilation et l'exécution.

Enfin, il y a un tas de ceci et de ce qui est plus ou moins optionnel:

  • docs dans doc
  • ressources en resources
  • données en data 
  • configuration dans conf...

Vous avez eu l'idée. Le compilateur ne se soucie pas de ces répertoires, ce ne sont que des moyens pour vous organiser (ou vous dérouter).

Projets J2EE

J2EE est à peu près équivalent à ASP.NET. Il s’agit d’un framework massif (standard) permettant d’organiser des applications Web. Bien que vous puissiez développer votre code pour les projets J2EE à votre guise, il existe un standard bien défini pour la structure à laquelle un conteneur Web s'attendra à ce que votre application soit livrée. Et cette structure tend également à refléter un peu la structure sourceVoici une page qui détaille les structures de projet pour les projets Java en général (ils ne sont pas très d'accord avec ce que j'ai écrit ci-dessus) et pour les projets J2EE en particulier:

http://maven.Apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

Projets Maven

Maven est un outil de création de projet très polyvalent. Personnellement, mes besoins de compilation sont bien satisfaits par ant, qui se compare approximativement à nmake. Maven, quant à lui, est une gestion de la construction de cycle de vie complet avec une gestion de la dépendance consolidée. Les bibliothèques et le code source de la plupart des codes du monde Java sont disponibles gratuitement sur le réseau, et maven, si on le lui demande bien, ira le parcourir pour vous et ramènera à la maison tout ce dont votre projet a besoin sans même avoir besoin de le lui dire. Il gère également un petit référentiel pour vous.

L'inconvénient de cette créature très industrieuse est le fait qu'elle est extrêmement fasciste quant à la structure du projet. Vous le faites à la manière de Maven ou pas du tout. En imposant sa norme dans la gorge, Maven parvient à rendre les projets mondiaux un peu plus similaires en structure, plus faciles à gérer et plus faciles à construire automatiquement avec un minimum d’intrants.

Si vous optez pour Maven, vous pouvez cesser de vous inquiéter de la structure du projet, car il ne peut en exister qu’une. C'est ça: http://maven.Apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

34
Carl Smotricz

Un paquetage en Java est très similaire à un espace de noms en .Net. Le nom du paquet crée essentiellement un chemin vers les classes qui y résident. Ce chemin peut être considéré comme l’espace de nom de la classe (en termes .Net) car c’est l’identifiant unique de la classe que vous souhaitez utiliser. Par exemple, si vous avez un paquet nommé:

org.myapp.myProject

Et à l'intérieur, vous avez eu un tas de cours:

MyClass1
MyClass2

Pour faire spécifiquement référence à ces classes, vous utiliseriez:

org.myapp.myProject.MyClass1
org.myapp.myProject.MyClass2

La seule différence réelle entre ceci et .Net (à ma connaissance) est que Java organise structurellement ses "espaces de noms" (chaque paquet est un dossier distinct), alors que .Net vous permet de définir des classes à l'aide du mot clé namespace et ignore l'emplacement réel vies.

Un fichier JAR est à peu près analogue à un DLL dans la plupart des cas. C'est un fichier compressé (vous pouvez les ouvrir avec 7Zip) qui contient le code source d'autres projets pouvant être ajoutés en tant que dépendances dans votre application. Les bibliothèques sont généralement contenues dans les fichiers JAR.

La chose à retenir à propos de Java est qu’elle est très structurelle; O les fichiers en direct sont importants. Bien sûr, il y a plus dans l'histoire que ce que j'ai posté, mais je pense que cela devrait vous aider à démarrer. 

13
dball917

Un paquet ressemble beaucoup à un espace de noms .Net. La convention générale en Java consiste à utiliser votre nom de domaine inversé comme préfixe de package. Par conséquent, si votre société est example.com, vos packages seront probablement:

com.example.projectname.etc...

Il peut être divisé en plusieurs niveaux plutôt qu’un seul (nom du projet), mais en général, un seul suffit.

Dans votre structure de projet, les classes sont généralement divisées en zones logiques: contrôleurs, modèles, vues, etc. Cela dépend du type de projet.

Il existe deux systèmes de construction dominants en Java: Ant et Maven.

Ant est fondamentalement un langage de script spécifique à un domaine et assez flexible, mais vous finissez par écrire vous-même beaucoup de choses complexes (tâches de construction, de déploiement, de test, etc.). C'est rapide et pratique cependant.

Maven est plus moderne et plus complet et vaut la peine d’être utilisé (à mon humble avis). Maven est différent de Ant en ce que Maven déclare que ce projet est un "projet d'application Web" (appelé archetype ). Une fois que cela est déclaré, la structure de répertoire est obligatoire une fois que vous spécifiez votre groupId (com.example) et votre artefactId (nom du projet).

Vous obtenez beaucoup de choses gratuitement de cette façon. Le véritable avantage de Maven est qu’il gère vos dépendances de projet. Ainsi, avec un pom.xml (fichier de projet Maven) correctement configuré, vous pouvez le donner à quelqu'un d'autre (avec votre code source), qui peut ainsi créer, déployer, tester et lancez votre projet avec les bibliothèques téléchargées automatiquement.

Ant obtient quelque chose comme ça avec Ivy.

7
cletus

Voici quelques notes sur les packages Java qui devraient vous aider à démarrer:

La meilleure pratique avec les noms de package Java consiste à utiliser le nom de domaine de l'organisation au début du package, mais inversement, par exemple. si votre entreprise est propriétaire du domaine "bobswidgets.com", vous lancerez votre paquet avec "com.bobswidgets". 

Le niveau suivant est souvent le niveau de l'application ou de la bibliothèque. Par conséquent, si ce sont vos bibliothèques de commerce électronique, cela peut ressembler à "com.bobswidgets.ecommerce". 

Plus bas, cela représente souvent l'architecture de votre application. Les classes et les interfaces qui sont au cœur du projet résident dans la "racine", par exemple. com.bobswidgets.ecommerce.InvalidRequestException.

L'utilisation de packages pour subdiviser davantage les fonctionnalités est courante. généralement, le modèle consiste à placer les interfaces et les exceptions dans la racine de la sous-division et dans les sous-packages, par exemple.

com.bobswidgets.ecommerce.payment.PaymentAuthoriser (interface)
com.bobswidgets.ecommerce.payment.PaymentException
com.bobswidgets.ecommerce.payment.Paypal.PaypalPaymentAuthoriser (implementation)

Il est donc très facile d’intégrer les classes et les packages "paiement" dans leur propre projet.

Quelques autres notes:

Les packages Java sont étroitement liés à la structure de répertoires. Ainsi, dans un projet, une classe avec un package de com.example.MyClass sera invariablement dans com/example/MyClass.Java. En effet, lorsque le fichier est compressé dans un fichier jar, le fichier de classe sera certainement dans com/example/MyClass.class.

Les packages Java sont faiblement couplés aux projets. Il est assez courant que les projets aient leur propre nom de package, par exemple. com.bobswidgets.ecommerce pour le commerce électronique, com.bobswidgets.intranet pour le projet intranet.

Les fichiers jar contiendront les fichiers de classe résultant de la compilation de votre code .Java en octets. Ce ne sont que des fichiers Zip avec l'extension .jar. La racine du fichier JAR est la racine de la hiérarchie des espaces de noms, par exemple. com.bobswidgets.ecommerce sera/com/bobswidgets/ecommerce/dans le fichier Jar. Les fichiers Jar peuvent également contenir des ressources, par exemple. fichiers de propriétés, etc. 

7
Jamie McCrindle

Un paquet est un groupe de fichiers source qui leur permet de voir les méthodes et les variables propres au paquet les uns aux autres, de sorte que ce groupe de classes puisse accéder à des éléments les uns des autres, contrairement aux autres classes.

On s'attend à ce que toutes les classes Java disposent d'un package utilisé pour les lever de l'ambiguïté. Donc, si vous ouvrez un fichier jar dans votre projet, comme spring, chaque paquet commence par org.springframework. Les chargeurs de classes ne connaissent pas le nom du fichier jar, ils n'utilisent que le paquet.

Il existe une pratique courante consistant à ventiler les objets par type d’objet ou fonction, mais tout le monde n’est pas d’accord sur ce point. Comme Cletus posté ici, il y a une tendance à regrouper les contrôleurs Web, les objets de domaine, les services et les objets d'accès aux données dans leurs propres packages. Je pense que certains responsables de la conception axée sur les domaines ne pensent pas que ce soit une bonne chose. Cela présente l'avantage que tous les éléments de votre paquet partagent généralement le même type de dépendances (les contrôleurs peuvent dépendre de services et d'objets de domaine, les services dépendent d'objets de domaine et d'accès aux données, etc.), ce qui est pratique.

Ok, donc en Java, vous avez trois types différents de accès à une classe membre fonctions et variables

public protégé paquet-privé et privé

Toutes les classes d'un même package peuvent se voir les unes des autres comme des éléments publics, protégés et des paquets privés. 

Les packages ne sont pas hiérarchiques dans le système. Ils sont généralement organisés de manière hiérarchique, mais en ce qui concerne l'exécution, com.example.widgets est un package complètement différent de com.example.widgets.cogs.

Les paquets sont organisés sous forme de répertoires, ce qui aide à garder les choses organisées: votre structure de fichier est toujours similaire à celle de votre paquet. 

Ils envisagent d'ajouter un système de modules à Java dans JDK7 (appelé Project Jigsaw ) et il existe un système de modules existant appelé OSGi . Ces systèmes de modules vous donneront/peuvent vous donner beaucoup plus de flexibilité et de puissance que le système de paquetage simple. 

En outre, les noms de paquetages sont généralement tous en minuscules. :)

3
Chad Okere

De Wikipedia:

Un package Java est un mécanisme pour organiser des classes Java en espaces de noms

et

Les packages Java peuvent être stockés dans fichiers compressés appelés fichiers JAR

Ainsi, pour le package a.b.c, vous pouvez avoir des classes Java dans les packages a, a.b et a.b.c. Généralement, vous regroupez des classes dans le même package lorsqu'elles représentent des fonctionnalités associées. Sur le plan fonctionnel, la seule différence entre les classes du même package et les classes de packages différents est que le niveau d'accès par défaut des membres en Java est "protégé par package", ce qui signifie que les autres classes du même package ont un accès.

Pour une classe abcMyClass, si vous souhaitez utiliser MyClass dans votre projet, vous devez utiliser import a.b.c.MyClass ou, moins recommandé, import a.b.c.*. De plus, si MyClass réside dans le paquet abc, vous devez le déclarer dans la première ligne de MyClass.Java : package a.b.c;.

Pour ce faire, vous pouvez créer le fichier JAR dans son intégralité (y compris les packages b et c et la classe MyClass) et mettre ce fichier JAR dans votre $CLASSPATH; cela le rendrait accessible à votre autre code source (via la déclaration d'importation susmentionnée).

2
danben

Pour répondre à l'exemple de sous-question:

package com.smotricz.goodfornaught;

import Java.util.HashMap;
import javax.swing.*;

public class MyFrame extends JFrame {

   private HashMap myMap = new HashMap();

   public MyFrame() {
      setTitle("My very own frame");
   }

}
2
Carl Smotricz

Les fichiers .JAR contiennent-ils du code compilé? Ou simplement des fichiers de code source compressés?

Ils peuvent contenir les deux, voire des types de fichiers totalement différents, comme des images. C'est tout d'abord une archive Zip. La plupart du temps, les JAR contenant des fichiers de classe et ceux contenant des fichiers source (pratique pour le débogage dans votre IDE si vous utilisez du code tiers) ou ceux contenant du javadoc (source de code source) sont également utiles si votre IDE prend en charge la navigation dans la documentation lorsque vous accédez aux fonctions de la bibliothèque.

Y a-t-il une bonne raison pour laquelle les noms de paquetages sont tous en minuscules? 

Oui, il existe une bonne raison pour que les noms de package soient écrits en minuscules: Il existe une directive qui dit que seuls les noms de classe sont écrits avec une majuscule devant.

Les packages peuvent-ils avoir des 'dépendances circulaires'? En d'autres termes, Package.A peut-il utiliser Package.B et vice versa?

Les paquets ne s'utilisent pas. Seules les classes font. Et oui, cela pourrait être possible, mais c'est une mauvaise pratique.

Quelqu'un peut-il simplement montrer la syntaxe typique pour déclarer une classe comme étant dans un package et indiquant que vous souhaitez référencer un autre package dans une classe (une instruction using peut-être?)

Supposons que vous souhaitiez utiliser la classe ArrayList du package Java.util, utilisez soit

 import Java.util.ArrayList;
 ArrayList myList = new ArrayList(); 

ou utilisez sans importer (par exemple, vous utilisez deux classes différentes nommées ArrayList à partir de packages différents)

 Java.util.ArrayList myList = new Java.util.ArrayList();
 your.package.ArrayList mySecondList = new your.package.ArrayList();
2
Tobias N. Sasse

Bien qu'il ne soit pas aussi facile de faire fonctionner les classes dépendantes circulaires, cela peut ne pas être impossible. Je l'ai fait fonctionner dans un cas. les classes A et B dépendent l'une de l'autre et ne compileraient pas à partir de rien. mais réalisant qu'une partie de la classe A n'avait pas besoin de la classe B, et que cette partie était ce dont la classe B avait besoin pour compiler complètement, je me suis souvenu de cette partie de la classe A, inutile pour la classe B, et du reste de la classe A était capable de compiler, puis de compiler la classe B. Je pouvais ensuite remanier cette section de la classe A qui nécessitait la classe B et pouvoir compiler la classe A. Les deux classes fonctionnaient alors correctement. Bien que ce ne soit pas typique, si les classes sont liées ainsi, c'est casher et parfois nécessaire. Assurez-vous simplement de vous laisser des instructions de compilation spéciales pour les futures mises à jour.

0