wake-up-neo.com

Java-Projektstruktur für Neulinge erklärt?

Ich komme aus einem .NET-Hintergrund und bin völlig neu in Java und versuche, mich mit der Java-Projektstruktur zu beschäftigen. 

Meine typische .NET-Lösungsstruktur enthält Projekte, die logisch verschiedene Komponenten bezeichnen, die normalerweise mit dem folgenden Format benannt werden: 

MyCompany.SomeApplication.ProjectName

Der Projektname entspricht normalerweise dem Root-Namespace für das Projekt. Wenn es sich um ein großes Projekt handelt, kann ich den Namespace möglicherweise weiter aufschlüsseln. Meistens sehe ich jedoch keinen weiteren Bedarf an Namespaces. 

In Java gibt es jetzt Anwendungen, die aus Projekten bestehen, und dann haben Sie eine neue logische Ebene - das Paket. Was ist ein paket Was soll es enthalten? Wie ist der Namespace innerhalb dieser App.Project.Package-Struktur? Wo passen JARs in all das? Kann grundsätzlich jemand eine Einführung in die Java-Anwendungsstruktur anbieten?

Vielen Dank!

Edit: Einige wirklich knackende Antworten, danke Jungs. Ein paar Folgefragen dann:

  • Enthalten .JAR-Dateien kompilierten Code? Oder einfach nur komprimierte Quellcode-Dateien?
  • Gibt es einen guten Grund, warum die Paketnamen alle Kleinbuchstaben sind?
  • Können Pakete zirkuläre Abhängigkeiten haben? Mit anderen Worten, kann Package.A Package.B verwenden und umgekehrt? 
  • Kann jemand nur die typische Syntax für das Deklarieren einer Klasse als in einem Paket enthalten angeben und angeben, dass Sie ein anderes Paket in einer Klasse referenzieren möchten (eine using-Anweisung vielleicht?)
45
MalcomTucker

"Einfache" J2SE-Projekte

Wie cletus erklärt hat, entspricht die Quellverzeichnisstruktur der Paketstruktur direkt und ist im Wesentlichen in Java integriert. Alles andere ist etwas weniger klar.

Viele einfache Projekte werden von Hand organisiert, sodass die Menschen eine Struktur auswählen können, mit der sie sich zufrieden fühlen. Was häufig gemacht wird (und dies spiegelt sich auch in der Projektstruktur in Eclipse, einem sehr dominanten Java-Tool) wider, ist, dass der Quellbaum in einem Verzeichnis namens src beginnt. Ihre paketlosen Quelldateien würden direkt in src gespeichert, und Ihre Pakethierarchie, die normalerweise mit einem com-Verzeichnis beginnt, wäre ebenfalls in src enthalten. Wenn Sie CD in das src-Verzeichnis wechseln, bevor Sie den javac-Compiler starten, befinden sich Ihre kompilierten .class-Dateien in derselben Verzeichnisstruktur, wobei sich jede .class-Datei im selben Verzeichnis und neben ihrer .Java-Datei befindet.

Wenn Sie über viele Quell- und Klassendateien verfügen, sollten Sie sie voneinander trennen, um das Durcheinander zu reduzieren. Manuelle und Eclipse-Organisation platzieren häufig ein bin- oder classes-Verzeichnis parallel zu src, sodass die .class-Dateien in einer Hierarchie enden, die die von src spiegelt.

Wenn Ihr Projekt über einen Satz von .jar-Dateien verfügt, um Funktionen aus Bibliotheken von Drittanbietern bereitzustellen, wird ein drittes Verzeichnis, normalerweise lib, parallel zu src und bin platziert. Alles in lib muss zum Kompilieren und Ausführen in den Klassenpfad gestellt werden.

Schließlich gibt es eine Menge davon und das ist mehr oder weniger optional:

  • docs in doc
  • ressourcen in resources
  • daten in data 
  • konfiguration in conf...

Du hast die Idee. Der Compiler kümmert sich nicht um diese Verzeichnisse, sie dienen lediglich dazu, sich selbst zu organisieren (oder zu verwirren).

J2EE-Projekte

J2EE entspricht in etwa ASP.NET und ist ein umfangreiches (Standard-) Framework zum Organisieren von Webanwendungen. Sie können zwar Ihren Code für J2EE-Projekte auf beliebige Weise entwickeln, es gibt jedoch einen festen Standard für die Struktur, in der ein Web-Container Ihre Anwendung erwartet. Diese Struktur spiegelt sich auch ein wenig im Quelllayout wiederHier ist eine Seite mit Details zu Projektstrukturen für Java-Projekte im Allgemeinen (sie stimmen nicht sehr mit dem überein, was ich oben geschrieben habe) und insbesondere für J2EE-Projekte:

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

Maven-Projekte

Maven ist ein sehr vielseitiges Werkzeug zum Erstellen von Projekten. Persönlich werden meine Build-Anforderungen von ant gut erfüllt, was ungefähr mit nmake vergleichbar ist. Auf der anderen Seite ist Maven das komplette Lifecyle-Build-Management mit dem Abhängigkeitsmanagement. Die Bibliotheken und Quellcodes für den Großteil des Codes in der Java-Welt sind im Netz frei verfügbar. Wenn Sie nett gefragt werden, wird maven es für Sie crawlen und alles mit nach Hause nehmen, was Ihr Projekt benötigt, ohne dass Sie es dazu sagen müssen. Es verwaltet auch ein kleines Repository für Sie.

Der Nachteil dieses sehr fleißigen Lebewesens ist die Tatsache, dass die Projektstruktur sehr faschistisch ist. Du machst es so oder so gar nicht. Maven schafft es, seinen Standard durchzusetzen, und schafft es, Projekte weltweit in der Struktur ein wenig ähnlicher zu machen, einfacher zu verwalten und einfacher zu erstellen, mit einem Minimum an Aufwand.

Sollten Sie sich jemals für Maven entscheiden, können Sie sich keine Gedanken mehr über die Projektstruktur machen, da es nur eine geben kann. Dies ist es: http://maven.Apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

34
Carl Smotricz

Ein Paket in Java ist einem Namespace in .Net sehr ähnlich. Der Name des Pakets erstellt im Wesentlichen einen Pfad zu den darin enthaltenen Klassen. Dieser Pfad kann als Namespace der Klasse (in .Net-Begriffen) betrachtet werden, da er die eindeutige Kennung für die bestimmte Klasse ist, die Sie verwenden möchten. Zum Beispiel, wenn Sie ein Paket haben:

org.myapp.myProject

Und darin gab es eine Reihe von Klassen:

MyClass1
MyClass2

Um speziell auf diese Klassen zu verweisen, würden Sie Folgendes verwenden:

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

Der einzige wirkliche Unterschied zwischen diesem und .Net (den ich kenne) ist, dass Java seine "Namespaces" strukturell organisiert (jedes Paket ist ein eigener Ordner), wohingegen .Net es Ihnen ermöglicht, Klassen mit dem Schlüsselwort namespace zu definieren und zu ignorieren, wo das Dokument tatsächlich ist lebt.

Eine JAR-Datei entspricht in den meisten Fällen einer DLL. Es ist eine komprimierte Datei (Sie können sie mit 7Zip öffnen), die Quellcode aus anderen Projekten enthält, die als Abhängigkeiten in Ihrer Anwendung hinzugefügt werden können. Bibliotheken sind im Allgemeinen in JARs enthalten.

Was bei Java zu beachten ist, ist sehr strukturell. WO Dateien live sind, ist wichtig. Natürlich enthält die Geschichte mehr als das, was ich gepostet habe, aber ich denke, damit sollte man anfangen. 

13
dball917

Ein Paket ähnelt einem .Net-Namespace. Die allgemeine Konvention in Java ist die Verwendung Ihres umgekehrten Domainnamens als Paketpräfix. Wenn Ihr Unternehmen example.com ist, werden Ihre Pakete wahrscheinlich wie folgt aussehen:

com.example.projectname.etc...

Es kann auf mehrere Ebenen anstatt auf nur eine (Projektname) aufgeteilt werden, aber in der Regel ist eine ausreichend.

In Ihrer Projektstruktur sind Klassen normalerweise in logische Bereiche unterteilt: Controller, Modelle, Ansichten usw. Dies hängt von der Art des Projekts ab.

In Java gibt es zwei dominante Build-Systeme: Ant und Maven.

Ant ist im Grunde eine domänenspezifische Skriptsprache und ziemlich flexibel, aber am Ende schreiben Sie selbst viel Boilerplate-Zeug (Erstellen, Bereitstellen, Testen usw.). Es ist jedoch schnell und bequem.

Maven ist moderner und vollständiger und lohnt sich (imho). Maven unterscheidet sich von Ant darin, dass Maven erklärt, dass dieses Projekt ein "Webanwendungsprojekt" ist (als archetype bezeichnet). Sobald dies festgelegt ist, wird die Verzeichnisstruktur festgelegt, sobald Sie Ihre groupId (com.example) und artifactId (Projektname) angeben.

Auf diese Weise erhalten Sie eine Menge kostenlos. Der wahre Vorteil von Maven ist, dass es Ihre Projektabhängigkeiten verwaltet, so dass Sie es mit einer pom.xml (Maven-Projektdatei) und korrekt konfiguriertem Maven an Dritte weitergeben können (mit Ihrem Quellcode) und sie können bauen, implementieren, testen und führen Sie Ihr Projekt mit Bibliotheken aus, die automatisch heruntergeladen werden.

Ant bekommt so etwas mit Ivy.

7
cletus

Hier einige Hinweise zu Java-Paketen, die Ihnen den Einstieg erleichtern sollten:

Bei Java-Paketnamen empfiehlt es sich, den Domänennamen der Organisation als Start des Pakets zu verwenden, umgekehrt, z. Wenn Ihr Unternehmen die Domäne "bobswidgets.com" besitzt, starten Sie Ihr Paket mit "com.bobswidgets". 

Die nächste Stufe ist oft die Anwendung oder die Bibliotheksebene. Wenn es sich um Ihre E-Commerce-Bibliotheken handelt, könnte dies etwa wie "com.bobswidgets.ecommerce" aussehen. 

Weiter unten steht oft die Architektur Ihrer Anwendung. Klassen und Schnittstellen, die den Kern des Projekts bilden, befinden sich in der "Wurzel", z. com.bobswidgets.ecommerce.InvalidRequestException.

Die Verwendung von Paketen zur weiteren Unterteilung der Funktionalität ist üblich. Normalerweise besteht das Muster darin, Schnittstellen und Ausnahmen in die Wurzel der Unterteilung zu setzen und die Implementierung in Unterpakete, z.

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

Dies macht es ziemlich einfach, die "Payment" -Klassen und -Pakete in ihr eigenes Projekt zu integrieren.

Einige andere Hinweise:

Java-Pakete sind eng an die Verzeichnisstruktur gekoppelt. Innerhalb eines Projekts befindet sich eine Klasse mit einem Package von com.example.MyClass daher immer in com/example/MyClass.Java. Dies liegt daran, dass sich die Klassendatei auf jeden Fall in com/example/MyClass.class befindet, wenn sie in ein Jar verpackt wird.

Java-Pakete sind lose an Projekte gekoppelt. Es ist durchaus üblich, dass Projekte eigene Paketnamen haben, z. com.bobswidgets.ecommerce für E-Commerce, com.bobswidgets.intranet für das Intranetprojekt.

Jar-Dateien enthalten die Klassendateien, die das Ergebnis der Kompilierung Ihres .Java-Codes in Bytecodes sind. Sie sind nur ZIP-Dateien mit der Erweiterung .jar. Der Stamm der Jar-Datei ist der Stamm der Namespace-Hierarchie, z. com.bobswidgets.ecommerce wird in der Jar-Datei/com/bobswidgets/ecommerce/sein. Jar-Dateien können auch Ressourcen enthalten, z. Eigenschaftsdateien usw. 

7
Jamie McCrindle

Ein Paket ist eine Gruppierung von Quelldateien, die es ihnen ermöglicht, die privaten Methoden und Variablen des jeweils anderen Pakets einzusehen, sodass diese Gruppe von Klassen auf Elemente ineinander zugreifen kann, auf die andere Klassen nicht zugreifen können.

Die Erwartung ist, dass alle Java-Klassen ein Paket haben, mit dem sie disambiguiert werden. Wenn Sie also wie im Frühjahr eine JAR-Datei in Ihrem Projekt öffnen, beginnt jedes Paket mit org.springframework. Die Klassenlader kennen den Namen der Jarfile nicht, sie verwenden nur das Paket.

Es ist üblich, die Dinge nach Objekttyp oder Funktion zu unterteilen, und nicht alle sind sich darüber einig. Wie Cletus hier veröffentlicht, besteht die Tendenz, Web-Controller, Domänenobjekte, Services und Datenzugriffsobjekte in ihren eigenen Paketen zusammenzufassen. Ich denke, einige Leute mit Domain-Driven-Design halten dies nicht für eine gute Sache. Es hat jedoch den Vorteil, dass in der Regel alles in Ihrem Paket dieselbe Art von Abhängigkeiten aufweist (Controller könnten von Diensten und Domänenobjekten abhängen, Dienste von Domänenobjekten und Datenzugriffsobjekten usw.), so dass dies bequem sein kann.

Okay, in Java gibt es drei verschiedene Arten von access auf Klassenfunktionen und -variablen

öffentlich geschützt paket-privat und privat

Alle Klassen in demselben Paket können alle öffentlichen, geschützten und privaten Elemente des Pakets sehen. 

Pakete sind im System nicht hierarchisch. Normalerweise sind sie hierarchisch organisiert, was jedoch die Laufzeit betrifft, ist com.example.widgets ein völlig anderes Paket als com.example.widgets.cogs

Pakete sind als Verzeichnisse angeordnet, um die Organisation zu erleichtern: Ihre Dateistruktur ähnelt immer Ihrer Paketstruktur. 

Sie planen, Java in JDK7 (genannt Project Jigsaw ) ein Modulsystem hinzuzufügen, und es gibt ein vorhandenes Modulsystem namens OSGi . Diese Modulsysteme werden/können Ihnen viel mehr Flexibilität und Leistung bieten als das einfache Paketsystem. 

Außerdem sind Paketnamen normalerweise alle Kleinbuchstaben. :)

3
Chad Okere

Von Wikipedia:

Ein Java-Paket ist ein Mechanismus für Java-Klassen in .__ organisieren. Namespaces

und

Java-Pakete können in .__ gespeichert werden. komprimierte Dateien, die als JAR-Dateien bezeichnet werden

Für Paket a.b.c können Sie Java-Klassen in den Paketen a, a.b und a.b.c haben. Im Allgemeinen gruppieren Sie Klassen innerhalb desselben Pakets, wenn sie verwandte Funktionen darstellen. Funktionsmäßig besteht der einzige Unterschied zwischen Klassen in demselben Paket und Klassen in verschiedenen Paketen darin, dass die Standardzugriffsebene für Mitglieder in Java "paketgeschützt" ist, was bedeutet, dass andere Klassen in demselben Paket Zugriff haben.

Wenn Sie für eine Klasse abcMyClass MyClass in Ihrem Projekt verwenden möchten, würden Sie import a.b.c.MyClass oder, weniger empfohlen, import a.b.c.*, verwenden. Wenn sich MyClass in Paket abc befindet, müssen Sie es in der ersten Zeile von MyClass.Java angeben : package a.b.c;.

Um dies zu tun, können Sie das gesamte Paket (einschließlich der Pakete b und c und der Klasse MyClass) JAR-Ups erstellen und diese JAR in Ihren $CLASSPATH einfügen. Dies würde es für Ihren anderen Quellcode (über die zuvor genannte Importanweisung) zugänglich machen.

2
danben

Um die Beispiel-Unterfrage zu beantworten:

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

Enthalten .JAR-Dateien kompilierten Code? Oder einfach nur komprimierte Quellcode-Dateien?

Sie können beides oder sogar ganz unterschiedliche Dateien wie Bilder enthalten. Es ist vor allem ein Zip-Archiv. Meistens werden JARs angezeigt, die Klassendateien enthalten, und solche, die Quelldateien enthalten (praktisch für das Debuggen in Ihrer IDE wenn Sie Drittanbietercode verwenden) oder solche, die Javadoc (Quellcode documentatin) enthalten Ihre IDE unterstützt das Aufrufen der Dokumentation beim Zugriff auf die Funktionen der lib.

Gibt es einen guten Grund, warum die Paketnamen alle Kleinbuchstaben sind? 

Ja, es gibt einen guten Grund dafür, dass Paketnamen in Kleinbuchstaben geschrieben werden: Es gibt eine Richtlinie, die besagt, dass nur Klassennamen mit einem Großbuchstaben geschrieben werden.

Können Pakete zirkuläre Abhängigkeiten haben? Mit anderen Worten, kann Package.A Package.B verwenden und umgekehrt?

Pakete verwenden einander nicht. Nur Klassen machen es. Und das könnte möglich sein, aber schlechte Praxis.

Kann jemand nur die typische Syntax für das Deklarieren einer Klasse als in einem Paket enthalten angeben und angeben, dass Sie ein anderes Paket in einer Klasse referenzieren möchten (eine using-Anweisung vielleicht?)

Angenommen, Sie möchten die ArrayList-Klasse aus dem Paket Java.util verwenden, entweder verwenden

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

oder ohne Import verwenden (beispielsweise verwenden Sie zwei verschiedene Klassen mit dem Namen ArrayList aus verschiedenen Paketen)

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

Es ist zwar nicht so einfach, zyklische abhängige Klassen zum Laufen zu bringen, aber es ist möglicherweise nicht unmöglich. Ich habe es in einem Fall zum Laufen gebracht. Klasse A und Klasse B waren voneinander abhängig und konnten nicht von Grund auf neu kompilieren. Aber als ich feststellte, dass ein Teil der Klasse A keine Klasse B benötigte und dieser Teil das war, was Klasse B vollständig kompilieren musste, entfernte ich diesen Teil der Klasse A, der für Klasse B nicht benötigt wird, und den restlichen Teil der Klasse A konnte kompilieren, dann konnte ich Klasse B kompilieren. Ich konnte dann den Abschnitt der Klasse A entfernen, der Klasse B benötigte, und konnte die vollständige Klasse A kompilieren. Beide Klassen funktionierten dann einwandfrei. Obwohl es nicht typisch ist, wenn die Klassen so miteinander verbunden sind, ist es koscher und manchmal notwendig. Stellen Sie einfach sicher, dass Sie sich spezielle Anweisungen für zukünftige Updates zusammenstellen.

0