Für den Use Case „Code Dokument erstellen“ generiere ich ein sogenanntes System Sequence Diagram. Das ist eine Sequenz an Nachrichten, die der Anwender mit dem System austauscht. Das System selbst wird dabei als black box betrachtet.
Inzwischen bin ich überzeugt, dass Potsmokers Einwände zu 95% korrekt waren. Ich habe Fehler gemacht. Ich bringe den Use Cases in ein vollständiges Format und ändere ein paar Dinge. Tatsächlich war der Begriff Datenbank unglücklich gewählt. Korrekt ist es zunächst bei einem Begriff zu bleiben, der aus der Welt der Problem-Domäne und nicht der Lösungs-Domäne angehört. Ich wähle also Code-Dokument Katalog statt Datenbank.
Ausserdem war es ein bischen design-overkill, den Anwender in die Rollen code-document producer, code-document consumer, etc. aufzuspalten.
Für dieses kleine System reicht eine Rolle Anwender, die mehrere Funktionen im System ausfüllt:
UC1: Code Dokument erstellenPrimärer Akteur: Anwender
Stakeholders and Interests:
[...] hier zu trivial
Main Success ScenarioPreconditions: Anwender ist im System authentifiziert
Postconditions: Das neue Code-Dokument ist im Code Dokument Katalog eingefügt.
Der Indexierungsservice hat das Code-Dokument indexiert.
Das Code-Dokument kann über die Kategoriesuche und die Volltextsuche jederzeit aufgerufen werden.
Main Success Scenario:1. Anwender startet Erstellung eines neuen Code Dokuments
2. Anwender fügt die benötigten textlichen Informationen (Beschreibung, Beschreibung der Verwendung, code)
3. Anwender wählt bei Bedarf aus der Liste der bestehenden LotusScript-Funktionen die aus, auf die der code im neuen Code-Dokument zugreift.
4. Anwender wählt die Kategorie des neuen Code Dokuments
5. Anwender teilt mit, dass Eingaben abgeschlossen.
6. System prüft Korrektheit der Eingaben.
7. Indexierungsservice indexiert Beschreibung.
8. System fügt Code Dokument dem Code-Dokument Katalog hinzu und persistiert diese Änderung in eine Datenbank (hehe).
9. System logged erfolgeiche Erstellung des neuen Code Dokuments.
10. System teilt Anwender mit, dass Code-Dokument erfolgreich dem Code-Dokument Katalog hinzugefügt wurde.
Extensions (or Alternative Flows)4. a) Anwender erstellt eine neue Kategorie -> Use Case „Neue Kategorie erstellen”
6.a) Anwender wird mit einer Nachricht auf die fehlenden Eingaben. Zurück zu 3.
7.a) Indexierung schlägt fehl
8.a) System fügt Code Dokument dem Code-Dokument mit dem Attribut „Code-Dokument nicht indexiert“ hinzu und persistiert diese Änderung in eine Datenbank.
9.a) System locked Erstellung des neuen Code Dokuments mit Hinweis auf fehlende Volltextindexierung.
10.a) System teilt Anwender mit, dass Code-Dokument erfolgreich dem Code-Dokument Katalog hinzugefügt, aber nicht volltextindexiert wurde.
11. Bei einem Neustart des Systems wird versucht den Volltextindex zu erstellen (Teil des startup Use Cases!).
8.a) Hinzufügung des Code Dokuments zum Code Dokument Katalog und ?ersistierung diese Änderung in eine Datenbank.scheitert.
9.a) System logged gescheitertes Hinzufügen des Code Dokuments zum Code Dokument Katalog
10.a) User erhält Nachricht über gescheitertes Hinzufügen des Code Dokuments zum Code Dokument Katalog
Man kann nun noch für das Main Success Scenario ein sogenanntes
System Sequence Diagram erzeugen. Das Sequence Sequence Diagram enthält die zwischen den Akteuren gesendeten Nachrichten. Dabei wird das System als Black Box betrachtet.
Ich habe ein bischen die Orthodoxie verlassen, indem ich nicht nur die Interaktion zwischen dem primären Akteur „Anwender“ und dem System zeige, sondern auch die Interaktion mit den sekundären Akteuren Datenbank, Indexierungsservice und Loggingservice. Ob das sinnvoll ist, kann ich nicht beurteilen. Eigentlich verliert das System dadurch ein wenig seinen (passiven) black box Charakter. Es ruft ja selber akiv die Operationen indexCodeDocument(), saveCodeDocument() und logMessage() auf.
Ich finde, man muß das nicht so päbstlich sehen. Modelle sind nie richtig oder falsch sondern immer mehr oder weniger nützlich. Bubbles don’t crash. An einem ausführbaren Programm kann in der Regel gut gezeigt werden, dass es nicht funktioniert. Bei einem Modell ist das schwieriger. Ein Modeller kann sich besser rausreden als ein Programmierer.
Da die deutsche Sprache in Computern sowieso meist zu einer kruden Mischung aus Deutsch und Englisch führt, nehme ich Englisch als Sprache. Als Input für die Namensfindung benutze ich den Text des Use Cases.
Beispiel:
Anwender wählt die Kategorie des neuen Code Dokuments
wird zur Operation selectCategory() usw.
Dieses generelle Vorgehen ist charakteristisch für den (Rational) Unified Process. Es wird sich von dem spezifischen Problem in der Welt der Anwender immer näher der Lösung, dem Computerprogramm angenähert. Auf dem Weg wird ein Haufen an Dokumenten erstellt. Bei jedem neuen Schritt wird auf die in die vorherigen Schritte erstellten Dokumente zurückgegriffen. Trotz aller Objektorientierung geht man also davon aus, dass die Domäne des Geschäftsprozesses, der durch die Software unterstützt werden soll, unterschiedlich ist von der Welt der Software. Ansonsten bräuchte man nicht diesen komplexen Analyseprozess. Mit Objektorientierung wird nur die semantische Lücke zwischen Geschäftsbereich und Software geringer, nicht geschlossen.
Die Kästchen oben beschreiben den Akteur. Ich stelle sie als UML-Objekte dar. Der Syntax von UML-Objekten ist
Objektbezeichner:Klassenbezeichner. Ich benötige keinen Objektbezeichner, deshalb nehme ich
:Klassenbezeichner. Die vertikalen gestrichelten Linien sind die Objektlebenslinien. Das Diagramm zeigt, dass die Akteurs-Objekte länger leben als die Zeitspanne des dargestellten Use Cases. Die Pfeile stehen für Nachrichten, die zwischen den Objekten ausgetauscht werden. Eine Nachricht ist: Objekt x ruft die Operation a des Objekts y auf.
Beispiel: Der Akteur User ruft die Operation selectFunctionsUsed() des System auf.
Die Begriffe Operation und Methode werden oft synonym verwendet. Das ist nicht ganz richtig. Eine Operation bezeichnet lediglich den Methoden-Header. Methode strenggenommen nur die Implementierung.
public String intToString(int num) {
return “” + num;
}
ist eine Methode. (Header und Body).
public String intToString(int num)
die entsprechende Operation der Klasse, die von ausserhalb oder innerhalb eines Objekts der Klasse angesprochen werden kann. Da wir uns im konzeptionellen Analyse-Modus und nicht im Implementierungs-Modus befinden, interessieren uns nur die Operationen, nicht die Methoden.
Rückgaben von Operationen können optional als gestrichelte Pfeile angezeigt werden. Der Anwender sendet dem System eine Nachricht, indem er dessen Operation saveCodeDocument() aufruft.
Dies führt zu einer Sequenz von Nachrichten, die zwischen den Akteuren System, Database, IndexService und LoggingService gesendet werden. Am Ende erhält der Anwender „message“ als Rückgabewert der Operation.
In diesem frühen konzeptionellen Diagramm habe ich auf Operationsparameter und die Spezifizierung der Rückgabewerte verzichtet. Ein Modell soll nicht die wirkliche Welt darstellen, sondern sich auf die wichtigen Dinge fokussieren. Bubbles don’t crash.
Von diesen Operationen lassen sich später die tatsächlichen Methoden des ausführbaren Systems ableiten.