Wie dokumentiere ich die Struktur eines Java-Programms?


20

Hintergrund: Meine Mitarbeiter und ich schreiben einen Artikel für eine akademische Zeitschrift. Im Zuge unserer Recherche haben wir ein Simulationsprogramm in Java geschrieben. Wir möchten das Simulationsprogramm für andere Benutzer frei verfügbar machen. Wir haben uns entschieden, den Code in einem GitHub-Repository zu hosten. Um anderen die Verwendung zu erleichtern, möchten wir eine gute Dokumentation für unser Programm schreiben, einschließlich:

  • Javadocs für jede Klasse und Methode
  • Wie man den Code benutzt
  • Beschreiben der übergeordneten Struktur des Codes

Meine übergeordnete Frage lautet: Können Sie ein gutes Beispiel für die Wörter und Diagramme angeben, mit denen die übergeordnete Struktur eines Programms beschrieben werden kann? Dies beinhaltet als Unterfragen:

  1. Wie zeigen wir, welche Klassen in welchen Paketen enthalten sind?
  2. Wie zeigen wir, welche Pakete von anderen Paketen abhängen?
  3. Wie zeigen wir, wie die Objekte / Klassen im Programm zusammenarbeiten?
  4. Wir haben versucht, bei der Gestaltung meines Codes domänenbasierte Gestaltungsprinzipien zu verwenden. Wie zeigen wir die Entsprechung zwischen den Objekten in der Domäne und den bestimmten Quellcodedateien, die diese Objekte codieren? (Siehe meine "allgegenwärtige Sprache" Beschreibung des Projekts unten.)

Was ich bisher gemacht habe

Allgegenwärtige Sprache

Wir haben eine "allgegenwärtige Sprache" -Beschreibung des Codes in eine Datei eingefügt ubiquitous-language.md, Inhalt siehe unten.

In diesem Projekt soll untersucht werden, wie gut eine Nachschubrichtlinie in einer einfachen Lieferkette mit einer einzigen Einrichtung unter verschiedenen Vorlaufzeitmodellen, Berichtsverzögerungen und Nachfragemodellen funktioniert.

In jedem Zeitraum treten die folgenden Ereignisse auf:

  1. Wenn geplant ist, dass eine Sendung im aktuellen Zeitraum in der Einrichtung eintrifft , wird der Lagerbestand der Einrichtung um X Einheiten erhöht.
  2. Wenn der Zeitplan angibt, dass die aktuelle Periode eine Berichtsperiode ist, sendet die Einrichtung einen Bericht an den Lieferanten . Der Lieferant kann den Bericht sofort oder mit einer Verzögerung von mehreren Wochen erhalten, wie im Zeitplan angegeben .
  3. Wenn der Lieferant einen Bericht erhalten hat , berechnet er basierend auf der Nachschubrichtlinie eine Nachschubmenge von X Einheiten. Eine Lieferung von X Einheiten des Produkts wird nach einer Vorlaufzeit von 1 Perioden eintreffen.
  4. Kunden kommen in der Einrichtung an und fordern X Einheiten des Produkts. Nicht erfüllte Forderungen gehen verloren.

Struktur des Quellcodes

Wir haben eine unvollständige "übergeordnete" Beschreibung des Codes in eine Datei eingefügt structure.md, deren Inhalt unten angegeben ist.

Struktur der Paketebene

Auf der höchsten Ebene ist der Quellcode in drei Pakete unterteilt

  • com.gly.sfs Die Hauptklasse mit der mainMethode befindet sich in diesem Paket.
  • com.gly.sfs.model Die Domänenmodellklassen befinden sich in diesem Paket.
  • com.gly.sfs.util In diesem Paket befinden sich Hilfsklassen.


Wenn Sie "Struktur des Codes auf hoher Ebene" sagen, meinen Sie damit nur, welche Klassen sich in welchen Paketen befinden? Sie können dies tun, indem Sie eine gepunktete Linie um die Klassen in Ihrem Klassendiagramm zeichnen, die zu einem bestimmten Paket gehören, und die gepunktete Linie mit dem Paketnamen kennzeichnen. Es ist einfach genug, Beispiele für Klassendiagramme zu finden .
Robert Harvey

Große Requisiten für die Veröffentlichung von akademischem Code.
Felix

@RobertHarvey Siehe meine Änderungen an der Frage. Es ist schwieriger zu zeigen, welche Klassen sich in welchen Paketen befinden, und wie die Klassen zusammenarbeiten.
Ich mag

1
Möglicherweise möchten Sie auch Javadoc auf Paketebene hinzufügen.
Haylem

Antworten:


4

Normalerweise verwenden Sie UML für den von Ihnen beschriebenen Zweck. UML gliedert sich grundsätzlich in zwei Arten von Diagrammen: Struktur und Verhalten.

Strukturdiagramme umfassen: Zusammensetzung, Bereitstellung, Paket, Klasse, Objekt und Komponente. Zu den Verhaltensdiagrammen gehören: Sequenz, Zustandsmaschine, Kommunikation, Anwendungsfall, Aktivität und Interaktionsübersicht.

Je nachdem, was Sie vermitteln möchten, wählen Sie einige dieser Diagramme aus, die am besten das darstellen, was Sie vermitteln möchten. Auf diese Weise können Sie der Konversation erlauben, "eine Ebene nach oben" zu gelangen. Anstatt über Methoden, Parameter und Code zu sprechen, sprechen Sie über Interaktionssequenzen oder statische Klassenabhängigkeiten oder über Diagramme, die Sie erstellen möchten.

Ich habe ein Beispiel eines Sequenzdiagramms angehängt (eines der Verhaltensdiagramme). Ich persönlich mag das Sequenzdiagramm, weil es sich mitten im Design-Artefakt-Prozess befindet - ungefähr die gleiche Anzahl von Diagrammen hängt davon ab, wie es als Eingabe erwartet wird. Ich finde, dass die Eingabediagramme in der Regel sowieso "verstanden" werden, oder das Sequenzdiagramm impliziert bereits ihre Existenz. Manchmal mache ich jedoch sowohl statische Klassendiagramme als auch Sequenzdiagramme (ein Struktur- und ein Verhaltensdiagramm).

http://omarfrancisco.com/wp-content/uploads/2011/07/sequencediagram.png

Ich habe dieses Diagramm noch nie in meinem Leben gesehen, aber ich kann eine Reihe von Dingen über dieses System erzählen. Es gibt vier Hauptkomponenten (die Substantive in Ihrem System - normalerweise die Klassen): View, Controller, Data Proxy und Data Provider. Die Pfeile sind "Verhalten" oder Methodenaufrufe. Ein Sequenzdiagramm ist grundsätzlich gut, um eine einzelne wichtige Interaktion zwischen einer Reihe von Komponenten darzustellen. Sie haben ein Sequenzdiagramm für jeden wichtigen Fluss durch Ihr System. Aus diesem Diagramm kann ich ersehen, dass "Controller" eine Methode namens "phoneIsComplete ()" verfügbar macht, die wiederum von der "lookupPhone ()" - Methode von DataProviderProxy abhängt, die wiederum von der "lookupPhone ()" - Methode von DataProvider abhängt.

Jetzt könnten Sie stöhnen und denken "uggg ... das gibt mir kein großes Bild des Systems - es sind nur individuelle Interaktionen durch das System". Abhängig von der Ausgereiftheit des Systems kann dies ein berechtigtes Problem sein (einfache Systeme kommen definitiv mit nur einer Sammlung von Sequenzdiagrammen aus). Wir gehen also zu den Strukturdiagrammen über und betrachten so etwas wie ein statisches Klassendiagramm:

http://www.f5systems.in/apnashoppe/education//img/chapters/uml_class_diagram.jpg

Klassendiagramme helfen uns dabei, zwei wichtige Dinge herauszufinden: Kardinalität und Klassenbeziehungstypen. Klassen können auf verschiedene Arten miteinander in Beziehung gesetzt werden: Assoziation, Aggregation und Zusammensetzung. Technisch gesehen gibt es einen Unterschied zwischen "statischen Klassenbeziehungen" und "Instanzbeziehungen". In der Praxis sehen Sie diese Linien jedoch unscharf. Der Hauptunterschied besteht darin, dass statische Klassenbeziehungen normalerweise keine Kardinalität beinhalten. Schauen wir uns das obige Beispiel an und sehen, was wir sehen können. Erstens können wir sehen, dass "Special Order" und "Normal Order" Untertypen von "Orders" (Vererbung) sind. Wir können auch sehen, dass ein Kunde N Bestellungen hat (dies können "normale Bestellungen", "Bestellungen" oder "Sonderbestellungen" sein) - das Kundenobjekt hat keine Ich weiß es wirklich nicht. Wir können auch eine Reihe von Methoden (in der unteren Hälfte jeder Klassenbox) und Eigenschaften (in der oberen Hälfte jeder Klassenbox) sehen.

Ich könnte noch lange über UML-Diagramme sprechen, aber das sind die Grundlagen. Hoffentlich hilft das.

TLDR; Wählen Sie ein Verhaltens- und ein strukturelles UML-Diagramm aus, lernen Sie, wie es erstellt wird, und Sie werden das erreichen, was Sie erreichen möchten.


18

Wenn Sie Schwierigkeiten haben zu beschreiben, wie die allgemeine Struktur Ihres Programms funktioniert und wie die Klassen gut zusammenarbeiten, sollten Sie die folgende Maxime in Betracht ziehen:

A picture is worth a thousand words.

Die Art und Weise, wie Sie ein Bild über Code malen, besteht darin , Codebeispiele bereitzustellen. Viele von ihnen. So legen Sie einen neuen Kunden (Code) an. So bearbeiten Sie eine Bestellung (Code). Dies gibt dem Benutzer Ihres Codes nicht nur einen Ausgangspunkt, sondern veranschaulicht auch, wie alle Objekte miteinander verbunden sind und interagieren. Wenn ich Ihren Code verwenden würde, wäre der größte Gefallen, den Sie mir tun könnten, viele Codebeispiele bereitzustellen.

Die Art und Weise, wie Sie ein Bild für einen Endbenutzer malen, besteht darin , Screenshots bereitzustellen. Viele von ihnen. Screenshot nach Screenshot, der veranschaulicht, ob Sie diese Aufgabe ausführen möchten, dies ist, was Sie zuerst tun, dies ist, was Sie als nächstes tun, usw.


+1, Codebeispiele für allgemeine Aufgaben sind das erste, was sich jemand wünschen wird, der versucht, eine API zu erlernen. Javadocs und eine Beschreibung der Beziehung zwischen Klassen füllen die Lücken aus, reichen jedoch nicht aus.
Doval

6
+1 für die UML nicht zu erwähnen.
Doc Brown

3
@DocBrown UML ist sicherlich nicht das Werkzeug für jeden Job. Allerdings , wenn Sie sich etwas Modellierung , dass passt das Muster eines der UML - Diagramme (zB Modellierung Klassenbeziehungen), dann UML hat ein Format anzubieten , die Leser wahrscheinlich zu kennen, und Vertrautheit Vereinfacht die Lesbarkeit.
Kat

@DocBrown Warum wäre UML in diesem Fall eine schlechte Lösung?
Onno

@Onno: Das war ein bisschen ironisch von mir, aber ich denke, UML hat nur begrenzte Unterstützung für eine solche "High-Level" -Beschreibung und eine sehr unklare Semantik. Die Verwendung von Paketdiagrammen ist hier jedoch in Ordnung (sofern das UML-Tool das Zeichnen von Klassen in Paketen zulässt).
Doc Brown

3

UML wird zwar häufig zum Modellieren von Software vor deren Erstellung verwendet, kann jedoch hilfreich sein. Es gibt verschiedene Diagramme, die Anwendungsfälle, Klasseninteraktionen usw. usw. veranschaulichen. Weitere Informationen finden Sie hier .


1

Ich finde https://www.websequencediagrams.com/ ein äußerst nützliches Werkzeug zur Beschreibung der Wechselwirkung zwischen den Komponenten innerhalb einer Anwendung oder zwischen Diensten in einer verteilten Anwendung. Dies vereinfacht lediglich die Erstellung und Pflege von UML-Sequenzdiagrammen erheblich.

Das Schöne ist, wenn Sie jede Lebenslinie als Schnittstelle oder Klasse in Ihrer Anwendung betrachten (ich modelliere normalerweise nur die großen Player), dann repräsentiert jede Zeile, die in diese Klasse fließt, eine Methode, die Sie unterstützen müssen.

Darüber hinaus gibt es einige Download-Optionen, um das Bild zu erhalten. Es gibt auch einige einfache Möglichkeiten, das Diagramm in ein Wiki einzubetten. Es ist daher ein hervorragendes Kommunikationsinstrument, um die Interaktion zwischen Komponenten oder Diensten in einem System zu beschreiben und dies mit dem Team zu kommunizieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.