Eine Projektstruktur in Eclipse zu erstellen ist eigentlich sehr simple. Eclipse bietet einen sogenannten "Workspace" an. Dieser enthällt alle Projekte die man gerade bearbeitet. Da man abhängigkeiten zwischen prjekten erstellen kann, bietet es sich an schon auf Projektebene mit der strukturierung zu beginnen.
Man hat dazu folgende Elemente zur Verfügung:
Einführung
Projekte (Java Projekte)
Im Workspace können beliebig viele Projekte liegen welche auch in Abhängigkeitsbeziehung zueinander treten können. --> Ausbildung einer Hierrarchie.
Projekte bestehen wiederum aus...
Source Folder
Jedes Projekt hat mindestens einen Ordner in welchem die eigentlichen Quellcode-Dateien liegen. Es kann aber sehr sinvoll mehrere Source Folder zu verwenden, z.B. um Testcode zu separieren.
Jeder Source Folder enthält wiederum...
Packete
Packete werden benutzt um Quellcodedateien zu bündeln. Anders als in Delphi kann jede Quellcode-Datei nur genau eine (von außen sichtbare und benutzbare) Klasse enthalten. Gehören mehrere Klassen inhaltlich zusammen werden sie üblicherweise im gleichen Packet untergebracht.
1. Idee - Semenatische Struktur
Ich hatte durch die Arbeit am PBM1 und PBM2 bereits ein recht gutes Verständnis davon, welche Entitäten mir im Spiel begegnen werden. Ich konnte sie grob unterteilen in Bau (Gebäude), Verband (Ligen, Nationen), Wirtschaft (Sponsoren, Konten) und Personen (Spieler, Manager). Meine erste Idee war deshalb folgende Gliederung:
Projekte
Es gibt 4 Hauptprojekte PBall3_Bau, PBall3_Verband, PBall3_Wirtschaft, PBall3_Personen. Zusätzlich gibt es ein Projekt PBall3_CoreIF welches die Interaces enthält und später sollte ein Projekt PBall3_Main die Startklassen und Hauptcontroller enthalten.
Die Hierrarchie sollte also sein (von oben nach unten, Projekte weiter oben sind abhängig von drunterliegenden projekten.):
Main
Bau, Verband, Wirtschaft, Personen
CoreIF
Source Folder
Von Anfang an war geplant JUnit tests zu benutzen um die Funktionsfähigkeit einzelner Einheiten zu testen.
Es wurden deshalb 2 Sourcefolder angelegt src\ sowie test\.
Die Packetstruktur in beiden war identisch. Die JUnit-Testklasse welche eine Klasse im Packet a.b.c im eigentlichen Sourceordner src\ testen sollte, lag im test\ Ordner im gleichnamigen Packet a.b.c
Packete
Der Quellcode wurde in den Hauptprojekten (Bau, Verband, ...) folgendermaßen gegliedert (Hier am Beispiel Personen):
Code: pball3.person allgemeine Klassen aus dem Personenbereich. (Alle nachfolgenden Packete lagen in diesem Packet) .data Enthielt die Datenspeicher (Entitäten) .control Enthielt die Controller welche die Entitäten füllten/auswerteten .gui Enthielt die Klassen zur visualisierung der Entitäten .factory Verband die Entitäten, Controller und GUIs zu einem Personenobjekt
Das CoreIF Projekt enthielt ebenfalls eine solche Packetstruktur. Allerdings ohne das Factory-Packet. Dafür aber für jeden Bereich (bau.data, person.data, wirtschaft.data, ...)
Wieso wurde diese Struktur nicht umgesetzt? Es stellte sich heraus, dass die unterteilung der Projekte probleme macht. Die semantische unterteilung ist zwar gut für die orientierung im Projekt allerdings hat sie ein fundamentales Problem: zyklische Abhängigkeiten zwischen den Projekten. Eigentlich sollte das CoreIF projekt dies verhindern. Die Controller und Entitys eines Hauptprojektes sollten nur mittels Interfaces mit den Klassen der anderen Hauptprojekte arbeiten. Dabei wurde vergessen, dass zumindest die Factorys zugriff auf die tatsächlichen Klassen benötigen.
Mein erster Reflex war alle Factorys in ein extra Projekt auszulagern, welches in der Hierrachie über den Hauptprojekten lag. Wenn ich nocheinmal drüber nachdenke könnte es sein, dass dies sogar funktionieren könnte(!), allerdings fehlte mir damals noch eine Idee: Damals sollten die Factorys die erstellten Klassen auch verwalten. Falls also jemand ein Team benötigte, sollte er per TeamFactory.getTeam(id) dieses erhalten. Dadurch hätten die Factorys aber von unten erreichbar sein müssen -> zyklus. Dieses Problem könnte ich im zweiten Ansatz durch das "Core" Projekt lösen, welches eine "globale Variable/Klasse" verwaltete über die man zugang zu allen teilen der PBall-Welt erhält.
2. Idee - Syntaktische Struktur
Da die Idee mit dem Code-Projekt erst im laufe der Idee2 kam, wurde Idee1 nicht weiter verfolgt. Die neue Gliederung sah so aus:
Projekte Es gibt 4 Hauptprojekte PBall3_Factory, PBall3_Data, PBall3_Control, PBall3_GUI. Zusätzlich gibt es ein Projekt PBall3_CoreIF welches die Interaces enthält und später sollte ein Projekt PBall3_Main die Startklassen und Hauptcontroller enthalten. (Auserdem kam noch das Projekt "PBall3_METAPROJEKT" hinzu welches nur dazu dient allgemein genutzte Bibliotheken zur verfügung zu stellen. Es liegt also sogar unter CodeIF)
Außerdem kam wie erwähnt das projekt PBall3_Core hinzu welches die Klasse PBallWeltManager enthielt, welcher wiederum die einzige PBallWelt die existiert (Singleton-Pattern) verwaltet/hält. Außerdem liegt dort noch der Zeitmanager, welcher das Datum im Spiel verwaltet.
Die Hierrarchie änderte ich dabei so (von oben nach unten, Projekte weiter oben sind abhängig von drunterliegenden projekten.):
Main Factory Control, Data, GUI Core CoreIF (METAPROJEKT)
Source Folder Das prinzip der 2 Sourcefolder blieb erhalten. (Funktioniert auch wunderbar.)
Packete Der Quellcode wurde in den Hauptprojekten (Factory, Control, Data, auch CoreIF) jetzt semeantisch gegliedert (Hier am Beispiel Factory):
Code: pball3.person Alle Factorys für verschiedene Personentypen pball3.bau Alle Factroys für gebäude (z.B. Stadion, Tribünen) pball3.wirtschaft Factorys aus der Wirtschaft pball3.verband Factorys für Sachen wie Nationen, Verbände, Ligen, ...
Das CoreIF Projekt enthält außerdem noch ein Packet mit Konstanten.
Die Idee2 ist stellt meine momentane Projektstruktur dar.
Idee1 steht senkrecht zu Idee2. Es sind 2 komplett verschiedene Sichtweisen auf das Problem. Falls die Idee1 auch mit dem Code-Projekt zyklische abhängigkeiten enthalten hätte würde dies meine These unterstützen, dass die Projektstruktur sich an den Bedürfnissen der Entwicklung orientieren muss, und nicht am verständniss des Packagings.
Ach ja. Für die nicht Javaner. Die Packetnamen sind in den unterschiedlichen Projekten nicht grundlos gleich. "protected" Eigenschaften sind sichtbar für alle Klassen des selben Packetes. Java ist dabei egal, ob das Packet über mehrere Projekte verteilt ist. Ich kann also mit den Factorys aus dem Factory-Projekt "protected"-Eigenschaften im Data-Projekt setzen. "Fachfremde" Klassen (die in anderen Packeten liegen) können da nicht ran, sondern müssen die "public" Getter und Setter nutzen. Das ist ziemlich praktisch - find ich.
Edit (10.9.07): Nach etliches Abhängigkeits-/Sicht-Problemen beim testen habe ich mich entschlossen die Test nicht per eigenen Sourcefolder Einzubinden. Ich habe vielmehr ein eigenes Subprojekt angelegt welches alle Tests enthält. Die Tests selbst liegen in der selben Packetstrucktur wie die zu testenden Klassen. Das Testprojekt liegt auf der obersten ebene und hat zugriff auf alle anderen Subprojekte. Sichtbarkeitsprobleme gehören damit der Vergangenheit an. ("Einfach ist meistens besser" )
Dateianhänge: |
Dateikommentar: Idee 2.
Lasst euch von den Pfeilen nicht verwirren. Wichtig ist nur eins: Die Schichten. Alle Pfeile gehen nur zu niedrigeren Schichten -> Kein Kreis.
![Idee2.jpg](./download/file.php?id=1570&sid=6590d848d67c6e5eb577a863dcac1297)
Idee2.jpg [ 22.94 KiB | 6956-mal betrachtet ]
|
Dateikommentar: Idee 1 mit herausgezogenen Factorys
![Idee1b.jpg](./download/file.php?id=1571&sid=6590d848d67c6e5eb577a863dcac1297)
Idee1b.jpg [ 20.38 KiB | 6956-mal betrachtet ]
|
Dateikommentar: Idee 1
![Idee1.jpg](./download/file.php?id=1572&sid=6590d848d67c6e5eb577a863dcac1297)
Idee1.jpg [ 22.08 KiB | 6956-mal betrachtet ]
|
|