Architectural Design WORKFLOW DESIGNDOKUMENT Softwareentwicklung Praktikum, Übungsbeispiel 2 Gruppe 86 Andreas Hechenblaickner [0430217] Daniela Kejzar [0310129] Andreas Maller [0431289] Gruppe 86 Seite 1
Architectural Design Example 2 1 Architectural Design 1.1 Module Das Programm wird in folgende Module aufgeteilt: Name Beschreibung Seite Modul Graph Modul Workflow Modul Input-Handler Modul Testprogramm Beschreibt die interne Speicherung eines gerichteten Graphen. Stellt Klassen mit Methoden zur Manipulation der im Graphen gespeicherten Knoten und Kanten zur Verfügung. Stellt die Klasse Workflow mit Methoden zur Verfolgung eines Pfades zur Verfügung. Verarbeitet eingegebene Kommandos und führt die entsprechenden Befehle aus. Leitet eingegeben Kommandos an den Input-Handler weiter und gibt Fehlermeldungen entsprechend an den Benutzer weiter. 3 5 9 12 Seite 2 Gruppe 86
Modul Graph 2 Modul Graph 2.1 Beschreibung Das Modul Graph stellt eine Datenstruktur zu Verfügung, die einen gerichteter, gewichteter Graphen speichert, welcher aus Knoten (nodes) und Kanten (edges) besteht. Dabei gilt das Knoten mit anderen Knoten durch Kanten verbunden werden. Die Datenstruktur stellt verschiedene Funktionalitäten, wie zb das Einfügen und Löschen von Knoten und Kanten bereit. Abbildung 1: Klassendiagramm Modul Graph 2.2 Erweiterungen Dieses Modul wird komplett aus dem 1. Übungsbeispiel übernommen und um einige Methoden erweitert. Klasse Graph Um die Anforderungen des 2. Übungsbeispiels zu erfüllen, wird von der Klasse Graph zusätzlich folgendes erwartet: getnodecount uint32 getnodecount(); Liefert die Anzahl der Knoten im Graphen zurück. getedgecount Verwendet: uint32 getedgecount(); Node::getEdgeCount Liefert die Anzahl der Kanten im Graphen zurück. Die Anzahl entspricht dabei der Summe der Kanten die von jedem Knoten ausgehen. Gruppe 86 Seite 3
Modul Graph Example 2 Klasse Node getedgecount uint32 getedgecount(); Liefert die Anzahl der Kanten, die von diesem Knoten ausgehen. Seite 4 Gruppe 86
Modul Workflow 3 Modul Workflow 3.1 Beschreibung Ein Workflow ist eine besondere Ausprägung eines Graphen. Es werden ein Guthaben (balance, Anfangswert 0) und zusätzlich Pointer auf drei besondere Knoten gespeichert: Startknoten (start) Zielknoten (target) Aktueller Knoten (current) Diese Knoten sind zu Beginn undefiniert. Die Klasse Workflow stellt Methoden bereit um Start- und Zielknoten zu setzten und Kanten zu folgen um den aktuellen Knoten zu ändern. Ziel ist es durch Verfolgung von Kanten den Zielknoten zu erreichen. Abbildung 2: Klassendiagramm Modul Workflow Anmerkungen Im Destruktor müssen zunächst die Pointer auf die drei besonderen Knoten (start, target und current) gelöscht (NULL-gesetzt) werden, da diese sonst vom Destruktor der Basiskasse Graph nicht gelöscht werden können (siehe Funktionalität deletenode). Gruppe 86 Seite 5
Modul Workflow Example 2 3.2 Funktionalität der Klasse Workflow setstartnodebyname void setstartnodebyname(std::string start_node_name); Verwendet: Graph::getNodeByName Wirft: NoSuchNodeException Setzt den Startknoten und den aktuellen Knoten (current) des Workflows auf den Knoten mit dem übergebenen Namen. Wirft eine NoSuchNodeExeption wenn der gesuchte Knoten nicht vorhanden ist. settargetnodebyname void settargetnodebyname(std::string target_node_name); Verwendet: Graph::getNodeByName Wirft: NoSuchNodeException Setzt den Zielknoten des Workflows auf den Knoten mit dem übergebenen Namen. Wirft eine NoSuchNodeExeption wenn der gesuchte Knoten nicht vorhanden ist. setbalance void setbalance(int32 balance); Setzt das Guthaben des Workflows auf den übergebenen Wert. Seite 6 Gruppe 86
Modul Workflow followedge bool followedge(std::string edge_name); Verwendet: Node::getSrcEdgeByName Edge::getDstNode Wirft: StartNodeUnsetException, NoSuchEdgeException Folgt ausgehend vom aktuellen Knoten des Workflows einer Kante mit dem übergeben Namen und ändert dabei den aktuellen Knoten auf den Zielknoten der Kante. Weiters wird das Guthaben angepasst, indem der Wert der verfolgten Kante abgezogen wird. Wirft eine StartNodeUnsetException wenn der Startknoten noch nicht definiert wurde oder eine NoSuchEdgeException wenn vom aktuellen Knoten keine Kante mit dem übergebenen Namen ausgeht. Gibt true zurück, wenn der Zielknoten erreicht wurden. deletenode Signature: Overrides: Wirft: void deletenode(std::string node_name); Graph::deleteNode NodeUndeleteableException Löscht den Knoten mit dem übergebenen Namen. Wird versucht einer der drei besonderen Knoten (start, target oder current) zu löschen, wird eine NodeUndeleteableException geworfen. Die Methode deletenode der Basisklasse Graph muss als virtual definiert werden! Gruppe 86 Seite 7
Modul Workflow Example 2 3.3 Fehlerbehandlung Zur Fehlerbehandlung werden zusätzlich zu den im Modul Graph definierten, folgende zusätzliche Exceptions zur Verfügung gestellt: Exception WorkflowException NodeUndeleteableException StartNodeUnsetException Beschreibung / Fehlermeldung Abstrakte Basisklasse für alle Fehlerfälle die in einem Worfklow auftreten können. error: unable to delete node error: start node is unset Abbildung 3: Klassendiagramm der Exceptions Seite 8 Gruppe 86
Modul Input-Handler 4 Modul Input-Handler 4.1 Beschreibung Aufgaben des Input-Handlers ist es eingelesene Kommandos zu verarbeiten und die entsprechenden Befehle mit ihren Parametern auszuführen. Ungültige Kommandos und Fehler beim Ausführen der Befehle, zb durch unvollständige/falsche Parameter, werden an das aufrufende Modul gemeldet. Abbildung 4: Klassendiagramm des Input-Handlers Eine Liste von erlaubten Befehlen mit ihren zugehörigen Objekten der Klasse BaseCommand, wird bei der Konstruktion des InputHandlers erzeugt. 4.2 Bereitgestellte Klassen Klassen InputHandler und GraphInputHandler Die Klassen InputHandler und GraphInputHandler entsprechen denen im Übungsbeispiel 1. Da die Trennung hier noch nicht sauber implementiert ist, wird dies nachgeholt. Gruppe 86 Seite 9
Modul Input-Handler Example 2 Klasse WorkflowInputHandler Der WorkflowInputHandler stellt zusätzlich Befehle zur Manipulation eines Workflows zur Verfügung. Zur Konstruktion muss ein Workflow-Objekt übergeben werden. Der WorkflowInputHandler kann folgende Befehle verarbeiten und auf den zugehörigen Graphen anwenden: Kommando set start <node> set target <node> set balance <balance> follow <edge> info Beschreibung Startknoten festlegen. Zielknoten festlegen. Guthaben festlegen. Kante verfolgen. Informationen über den Workflow anzeigen. Dies beinhaltet: Anzahl der Knoten, Anzahl der Kanten, Startknoten, Zielknoten und aktueller Knoten (bzw "undefiniert") sowie das verbleibende Guthaben. Klasse BaseCommand Für jeden verfügbaren Befehl ist eine eigene, von BaseCommand abgeleitete Klasse verfügbar. Die virtuelle Methode executecommand implementiert jeweils den auszuführenden Code. Abbildung 5: Verfügbare Command-Klassen Seite 10 Gruppe 86
Modul Input-Handler StringTokenizer Zur einfachen Verarbeitung der übergeben Befehlszeile wird diese zunächst von einer eigenen Klasse StringTokenizer in ihre einzelnen Wörter zerlegt. Ein Aufruf der Methode getnexttoken liefert immer das jeweils nächste Wort, solange hasmoretoken wahr zurückliefert. Erweiterung Der StringTokenizer wird um eine Methode getnexttokenasint erweitert, die das nächste Token ermittelt und dabei probiert dieses in einen Integer umzuwandeln. Ist die Umwandlung nicht möglich, wird eine StringParseException geworfen. Gruppe 86 Seite 11
Modul Testprogramm Example 2 5 Modul Testprogramm 5.1 Beschreibung Das Testprogramm stellt Befehle zur Verfügung mit der ein Workflow bearbeitet werden kann. Dazu wird zunächst ein leeres Workflow-Objekt erstellt. Es wird eine Eingabeauforderung angezeigt, in der der Benutzer eine Reihe von durch das Modul Input-Handler definierte Befehle zur Manipulation eines Workflows eingeben kann. Das Testprogramm ist dafür verantwortlich das alle vom Workflow und vom Input-Handler weitergereichte Exceptions durch ihre entsprechende Fehlermeldungen dargestellt werden. Das Testprogramm besteht lediglich aus der Klasse TestProgram und wird über die Methode run vom Hauptprogramm aus gestartet. Abbildung 6: Klassendiagramm Modul Testprogramm Erweiterung Das Testprogramm bleibt grundsätzlich unverändert, es wird lediglich statt eines Graphen ein Workflow-Objekt erzeugt. Seite 12 Gruppe 86
Automatisierte Testläufe 6 Automatisierte Testläufe 6.1 Beschreibung Um das Programm automatisch auf Fehler zu überprüfen, wird eine Liste von Befehlen in einer Datei bereitgestellt. Diese können dann einfach mittels workflow < testinput.txt in das Programm eingelesen und verarbeitet werden. Danach lässt sich die Ausgabe mit einer zuvor händisch erstellten Referenz-Ausgabe vergleichen. Die erledigt zum Beispiel das Programm diff und kann somit bequem zb in das Makefile eingebaut werden. Verschieden Testfälle werden mit anderen Gruppen gemeinsam erarbeitet und ausgetauscht. Testfälle vom 1. Übungsbeispiel müssen bis auf den Befehl show weiterhin erfolgreich ausgeführt werden. Gruppe 86 Seite 13