Reverse Engineering Konzept zur Gewinnung von Verhaltensinformationen aus objektorientierter Software

Reverse Engineering Konzept zur Gewinnung von Verhaltensinformationen aus objektorientierter Software Carsten C. Freining, Vicente Ferreira de Lucena ...
Author: Frauke Hofmann
3 downloads 3 Views 40KB Size
Reverse Engineering Konzept zur Gewinnung von Verhaltensinformationen aus objektorientierter Software Carsten C. Freining, Vicente Ferreira de Lucena Jr.∗) Institut für Automatisierungs- und Softwaretechnik Universität Stuttgart

Kurzfassung Die Entwicklung von Software geht immer mehr in Richtung Wiederverwendbarkeit und Wartbarkeit von Softwaresystemen. Durch Modellierung von Architektur und Verhalten wird die Aufgabe des Wartens oder Weiterentwickelns dieser Systeme wesentlich vereinfacht. Problematisch bleiben die alten Softwaresysteme, die nicht in modellierter Form vorliegen. Mit Hilfe von Werkzeugen gelingt es nur Architekturinformationen wieder zu gewinnen. Das Verhalten kann nur dann rekonstruiert werden, wenn der Code vom gleichen Werkzeug generiert wurde. Dieser Artikel stellt ein Konzept für das automatisierte Reengineering von Verhaltensbeschreibungen aus bestehendem, objektorientiertem Quellcode vor. Die Codeanalyse wird mit mehreren Parsern durchgeführt, dabei werden die notwendigen Daten für das Sequenzdiagramm und Zustandsdiagramm herausgelesen. Anschließend werden die Daten ausgewertet und in eine grafisch darstellbare Form gebracht.

1. Einführung Moderne Methoden und Konzepte der Softwareentwicklung machen es möglich, einfacher und damit schneller neue, komplexere Software zu entwickeln. Durch die Anwendung dieser Methoden wird es auch einfacher, Software zu verstehen und Fehler der Softwarearchitektur oder des Laufzeitverhaltens zu finden. Eine Darstellungsmöglichkeit in der objektorientierten Softwaretechnik ist die Unified Modeling Language (UML) [1]. Mit ihren Beschreibungsformen ist es möglich, die Architektur und das Verhalten von objektorientierter Software zu modellieren und darzustellen. Das Problem stellt die Beschreibung der bestehenden Software dar, die noch nicht mit diesen neuen Methoden oder mit den neuen Konzepten entwickelt wurde. Entwicklungswerkzeuge können nur das Klassendiagramm mit den Klassendefinitionen wieder herstellen. Die Verhaltensbeschreibung kann nur zurückgewonnen werden, wenn die Software mit dem gleichen Werkzeug entwickelt und generiert wurde. Das Werkzeug fügt bei der Generierung Kommentare in den Code ein, mit denen es das Verhaltensmodell wieder herstellen kann. Dieses Round-Trip-Verfahren funktioniert aber nicht bei beliebiger Software. Die Verhaltensbeschreibung kann meist nur durch Handarbeit in eine neue Darstellungsform überführt werden. In diesem Artikel wird ein Ansatz vorgestellt, durch Codeanalyse eine Verhaltensbeschreibung zu erstellen oder wieder herzustellen. Die Motivation ist es, eine Möglichkeit zu finden, diesen Schritt zu automatisieren, ohne eventuelle Kommentare mit ein zu beziehen. Diese Automatisierung basiert auf der Technik, den Code mittels eines Parsers nach den für die Beschreibung notwendigen Informationen zu durchsuchen, diese weiter zu verarbeiten und in eine verhaltensbeschreibende Form zu bringen. Der nächste Abschnitt wird einige grundlegende Aussagen über die verschiedenen Voraussetzungen des Ansatzes und die Ergebnisdarstellung machen. Der dritte Abschnitt wird sich mit dem ausgearbeiteten Konzept befassen. Dabei wird zuerst ein Überblick über das Konzept gegeben (Kapitel 3.1), dann auf den Vorgang und die Datenstrukturen für das Sequenzdiagramm (Kapitel 3.2) und das Zustandsdiagramm (Kapitel 3.3) getrennt eingegangen. Im darauf folgenden Abschnitt wird das Konzept anhand einer C++ Steuerungssoftware bewertet. Den Abschluss bildet eine Zusammenfassung mit Ausblick.

∗)

Stipendiat der brasilianischen Regierung - CNPq

2. Grundlagen 2.1

Die Voraussetzungen

Der Ansatz geht von beliebigem objektorientiertem Code aus. Dynamische Vorgänge, wie zum Beispiel das dynamische Binden von Methoden zur Laufzeit, werden nicht in die Betrachtung einbezogen. Aus dem beliebigen objektorientierten Code kann das Klassendiagramm bereits von einem Werkzeug gewonnen werden. Dabei werden die Verbindungen und Abhängigkeiten der einzelnen Objekte der jeweiligen Klassen erkannt und in einem Klassendiagramm dargestellt. Mit diesem Diagramm sind auch die einzelnen Klassendefinitionen und die Objektinstanzen der Klassen bekannt. Diese Informationen werden für den Ansatz als gegeben angenommen. 2.2

Die Ergebnisdarstellung

Die Ergebnisse des Ansatzes werden in tabellarischer Form angegeben. Aus den Tabellen soll es möglich sein, die einzelnen grafischen Notationen der Verhaltensbeschreibung zu erstellen. In diesem Fall wird es sich um das Sequenzdiagramm und das Zustandsdiagramm der UML handeln. Als Einführung werden die einzelnen Diagramme der UML an einem Beispiel erklärt. Die wichtigen Beschreibungsformen für diesen Artikel sind das Klassendiagramm, das Sequenzdiagramm und das Zustandsdiagramm. Das Klassendiagramm beinhaltet die Definitionen der einzelnen Klassen, die Verbindungen und Abhängigkeiten der Objekte der jeweiligen Zylinder Aktor Klasse. Initialisierung() AKTOR()

Ausfahren() Aktor_setzen()

Fehler

Fehler

Abbildung 1: Beispielkommunikation zwischen einem Objekt Zylinder und einem Objekt Aktor

Das Sequenzdiagramm beschreibt die Kommunikation zwischen den einzelnen Objekten [2]. Der Nachrichtenaustausch besteht aus Methodenaufrufen und Rückgabewerten, die als Antwort bezeichnet werden können. Es gibt für den Kommunikationsverlauf innerhalb einer Software mehrere Möglichkeiten. Diese unterschiedlichen Verläufe, auch Szenarien genannt, werden durch verschiedene Sequenzdiagramme dargestellt. Die einzelnen Szenarien ergeben sich durch äußere Einflüsse auf das Softwaresystem. Die Abbildung 1 zeigt ein Beispiel für einen Nachrichtenaustausch.

Das Zustandsdiagramm spiegelt den Lebenszyklus eines Objektes wieder [2]. Der Lebenszyklus wird durch Zustände und Zustandsübergänge dargestellt. In einem Zustand wartet das Objekt auf ein Ereignis, um in einen anderen Zustand überzugehen. Diese Zustandsübergänge werden durch die Methoden eines Objektes realisiert. Eine Methode kann ein Objekt abhängig vom Anfangszustand in unterschiedliche Endzustände überführen. Ein Beispiel für ein Zustandsdiagramm wird in Abbildung 2 gegeben. Erzeugung

Ausfahren Zylinder eingefahren

Zylinder ausgefahren Einfahren Terminierung

Terminierung

Abbildung 2: Beispiel eines Zustandsdiagramms für ein Zylinderobjekt

3. Das Reengineering Konzept 3.1

Übersicht

Die Vorgehensweise ist für das Sequenz- und Zustandsdiagramm gleich. Unterschiede ergeben sich aus den gesuchten Informationen und der Strukturierung in der Zwischendarstellung. Abbildung 3 zeigt eine Übersicht des Vorgangs. Der erste Schritt ist die Top Down Codeanalyse durch einen Parser. Wegen der unterschiedlichen Struktur der Zwischendarstellungen, für das Sequenzdiagramm und das Zustandsdiagramm, werden zwei verschiedene Parser benötigt. Die Parser erstellen für jedes der beiden Diagramme eine getrennte Zwischendarstellung in tabellarischer Form. Die beiden Zwischendarstellungen enthalten die notwendigen Informationen in der Reihenfolge, in der die Parser die Daten aus dem Code ausgelesen haben. Im zweiten Schritt werden die Daten ausgewertet und in die für das entsprechende Diagramm benötigte Form gebracht.

Parser Code Daten Auswertung

Zwischendarstellungen

Zustände

Sequenzdiagramm

Übergänge

Abbildung 3: Der automatisierte Reengineeringvorgang 3.2

Die Sequenzdiagramme

Ein Sequenzdiagramm zeigt ein Szenario der Kommunikation zwischen den Objekten innerhalb der Software. Das Szenario ist abhängig von den äußeren Einflüssen. Um die verschiedenen Szenarien in der Software zu realisieren, werden die äußeren Einflüsse durch Bedingungsabfragen im Code überprüft. Dadurch wird der Programmfluss verzweigt. Je nach Bedingung werden unterschiedliche Anweisungen ausgeführt. Die Bedingungsabfragen stehen vor allem in Schleifen und Programmverzweigungen wie zum Beispiel if ... else oder switch Anweisungen. Diese unterschiedlichen Programmpfade müssen in der Zwischendarstellung für das Sequenzdiagramm erkennbar sein. Die Tabelle 1 zeigt die Struktur der Zwischendarstellung. Spaltenüberschrift Methode Rückgabevariable

Aufgerufenes Objekt Aufgerufene Methode

Methodenparameter

Verzweigungsindex Schleifenindex

Bedeutung Die aktuell untersuchte Methode. 1. Gibt die Variable an, der der Rückgabewert zugewiesen wird. 2. Gibt im Falle einer Verzweigung oder Schleife mit Variabelenabhängigkeit die Bedingungsvariable an. Objekt, dessen Methode aufgerufen wird. 1. Die aufgerufene Methode. 2. Gibt die Schleifenart oder Verzweigungsart an. Es wird der Schleifenanfang und das Schleifenende sowie der Verzweigungsanfang und das Verzweigungsende über diesen Eintrag angegeben. 1. Parameter der Methode. 2. Gibt im Falle einer Verzweigung oder Schleife mit Variabelenabhängigkeit die Bedingung selbst an. Index für den Verzweigungspfad Index für die Schleifentiefe

Tabelle 1: Die Struktur der Zwischendarstellung des Sequenzdiagramms

Die Daten werden in der vom Parser ausgelesenen Anordnung gespeichert. Die für die Zwischendarstellung ausgelesenen Informationen sind: Die Methodenaufrufe, mit der zugehörigen Rückgabevariablen und Parametern, die Schleifeninformationen, wie Schleifenanfang, Schleifenende, Schleifenbedingung und die verschiedenen Verzweigungen mit ihren Bedingungen. Um das Vorgehen bei der Auswertung zu vereinfachen wird in der Zwischendarstellung für jede Klasse eine eigene Tabelle erstellt. In diesen Tabellen bilden die Daten für eine Methode eine Teilsequenz. Für die Funktion „main“wird ebenfalls eine Teilsequenz erstellt, die in einer eigenen Tabelle gespeichert wird. Jede Teilsequenz enthält die Informationen in der vom Parser gelesenen Reihenfolge. Für das Sequenzdiagramm müssen die Daten in die zeitliche Reihenfolge gebracht werden. Dies wird durch die Schachtelung der verschiedenen Teilsequenzen erreicht (Abbildung 4). Die Tabelle der Funktion „main“ stellt die Basistabelle der Schachtelung dar. Die einzelnen Zeilen werden durchsucht, bis ein Methodenaufruf gefunden wird. Der Methodenaufruf wird in den Objektnamen und den Methodennamen aufgeteilt. Durch die Objektzugehörigkeit kann der Methode eine Klasse zugeordnet werden. Es wird die entsprechende Teilsequenz der aufgerufenen Methode in die Tabelle eingefügt. Dieses Vorgehen wird fortgesetzt, bis die letzte Zeile der Tabelle untersucht wurde. Diese resultierende Tabelle enthält nun die zeitliche Reihenfolge der Kommunikation. Durch das Einbinden der Schleifen und Bedingungen in den Kommunikationsverlauf werden die Elemente des Kontrollflusses mit dem Sequenzdiagramm vereint. Das Ergebnis kann als allgemeines Sequenzdiagramm angesehen werden, das alle möglichen Sequenzen der Software enthält.

Klasse A

Klasse B

Klasse C

Teilsequenzen

Teilsequenzen

Teilsequenzen

main Nachrichtenfolge Abbildung 4: Die Schachtelung der einzelnen Teilsequenzen Wie ein allgemeines Sequenzdiagramm aussieht, zeigt Abbildung 5. Die Zeitachse für ein Objekt wird verzweigt, um die einzelnen Programmpfade darzustellen. Schleifen werden durch einen Rückführungspfad vom Schleifenfuß zum Schleifenkopf gebildet. Die Bedingungen für die Verzweigungen oder Schleifen werden an den zugehörigen Verzweigungs- oder Rückführungspfad angehängt. Aus diesem allgemeinen Sequenzdiagramm können alle möglichen Sequenzdiagramme abgelesen werden.

main

Schnittstelle

Bohrer

Eingabegerät

Positionierer

Schleifenkopf Abfrage(Parameter) Wert_Ablesen(Parameter) Abgelesener_Wert Wert Wert= positionieren

Wert= bohren bohren(Parameter)

Abfrage_Bohrerposition() feste_position

positionieren(Parameter)

Fehler Bohrerposition_Anfahren()

position_erreicht Fehler

Abfrage(Parameter)

Wert_Ablesen(Parameter)

Abgelesener_Wert

Wert

Wert=Weiter

Abbildung 5: Beispiel eines allgemeinen Sequenzdiagramms

3.3

Das Zustandsdiagramm

Um das Zustandsdiagramm eines Objektes erstellen zu können, werden alle real eingenommenen Zustände und die zugehörigen Zustandsübergänge benötigt. Der Zustand eines Objektes wird durch die Wertekombinationen seiner Attribute definiert. Werden zuerst alle möglichen Wertekombinationen aufgenommen, so explodiert der Zustandsraum für mögliche kontinuierliche Attributstypen. In der Realität werden die Attributswerte durch Bedingungsabfragen im Code zu Wertebereichen zusammengefasst. Diese Wertebereiche ergeben sich durch die Analyse der Methoden eines Objektes. Jede Methode kann mehrere Endzustände haben. Der Zustandsraum eines Objektes wird durch die Endzustände aller Methoden des Objektes festgelegt. Um die Zustände aus der Zwischendarstellung ablesen zu können, werden die Daten während des Parsens in einer Baumstruktur gespeichert. Die Verzweigung im Code ergibt die Verzweigungen in der Baumstruktur. Ein Zweig, der während der Analyse keinen Nachfolger hat, wird momentaner Endzweig genannt. Jede weitere Zeile Code muss für jeden momentanen Endzweig gesondert untersucht werden. Jeder Zweig kennt alle seine Attributswerte oder Wertebereiche. Wie der zugehörige Baum einer Methode aussieht, zeigt Abbildung 6. Um in der Abbildung eine Trennung zwischen den einzelnen Zweigen zu haben werden die Zweigenden durch einen Knoten abgeschlossen. Die Variable Attribut_A ist ein Attribut des Objektes und ist eine 32 Bit Integer Zahl. Die lokale Variable zaehler wird immer mitgeführt. Sie kann zu Verzweigungen mit unterschiedlichen Endzuständen führen. Zur Beschreibung des Endzustandes trägt sie jedoch nicht bei. Für den äußeren Betrachter kann auch der Rückgabewert einer Methode von Bedeutung sein. Dieser Wert wird deshalb als Zustandsrelevant eingestuft. Ist der Rückgabewert ein Fehlercode, so kann es sein, dass das System auf den Rückgabewert entsprechend reagieren wird. Für den inneren Zustand des Systems hat der Rückgabewert keine Auswirkungen. Wird der Wert einer Variable zurückgegeben, so wird als Rückgabewert der Variablenname aufgenommen. Aus den aufgenommenen Daten kann der Wert oder der Wertebereich herausgelesen werden. Am Ende des Parserdurchgangs werden die momentanen Endzweige zu den Blättern des Baumes und geben die möglichen Endzustände der Methode wieder. Für jede Methode ergibt sich ein Baum.

Die Blätter aller Bäume werden nun zur gesamten Anzahl der Zustände eines Objektes zusammengenommen. Da jeder Baum einer Methode zugeordnet ist, können den Endzuständen die entsprechenden Zustandsübergänge zugeordnet werden.

Wurzel

byte Methode_A() { int zaehler=0;

zaehler= 0

do { Attribut_A = get_value();

Attribut_A= 0..4 294 967 296

zaehler++; zaehler= zaehler+1

} while ((!( Bed.(Attribut_A) )) && ( Bed.(zaehler) ));

Bedingung(Attribut_A) = Falsch && Bedingung(zaehler) = Falsch

if (!( Bed.(Attribut_A) ))

Bedingung(Attribut_A) = Wahr && Bedingung(zaehler) = Wahr

{

Bedingung(Attribut_A) = Wahr && Bedingung(zaehler) = Falsch

return -1; } else { return 0; } }

Endzustände Attribut_A Rückgabewert

Abbildung 6: Darstellung einer Baumstruktur für eine Beispielmethode Methode_A. Die Zustandsübergänge müssen noch genauer untersucht werden. Ein Zustandsübergang wird durch einen Anfangszustand, einen Endzustand und die zugehörige Methode beschrieben. Für einen bedingten Zustandsübergang wird im Code der Anfangszustand mittels Bedingungsabfragen überprüft. Diese Bedingungsabfragen stehen vor einer Änderung des entsprechenden Attributs. Es wird also eine Markierung für jedes Attribut eingeführt, die anzeigt, ob das entsprechende Attribut geändert wurde. Wird eine Bedingungsabfrage durchgeführt, so muss die entsprechende Bedingung für jeden weiteren Zweig mit aufgenommen werden. Es muss erkennbar sein, dass eine Änderung der Attribute von dieser Bedingung abhängt. Von dieser Abhängigkeit kann der Anfangszustand eines Übergangs abgelesen werden. Die Daten werden wie bei der Zwischendarstellung für das Sequenzdiagramm in tabellarischer Form gespeichert. Jeder Zweig muss seinen Vorgänger kennen. Mit diesem Wissen wird die Baumstruktur innerhalb der Tabelle realisiert. Die Tabelle 2 zeigt die Struktur der Zwischendarstellung für das Zustandsdiagramm. Dabei ist anzumerken, dass der Variablenbereich eine Spalte für jedes Attribut und jede lokale Variable ergibt. Spaltenüberschrift

Bedeutung

Zweigindex

Index, der den Zweig in der Baumstruktur identifiziert.

Index des Vorgängerzweiges

Identifiziert den Vorgänger für diesen Zweig.

Befehl

Gibt die Programmanweisung in der untersuchten Zeile wieder.

Bedingungen für die Attribute

Eine Bedingung, die diesen Zweig ausmacht. Sie müssen in Einklang mit den Bedingungen aus Vorgängerzweigen sein.

Variablenbereiche

Jede Variable bekommt eine eigene Spalte. Es werden auch lokale Variablen und übergebene Parameter aufgenommen. Jedes Attribut bekommt einen Marker, der anzeigen soll, ob der Wert dieser Variable verändert wurde.

Endpunkt

Die Markierung für einen Endpunkt. Zweige mit dieser Markierung geben einen Endzustand einer Methode wieder.

Tabelle 2: Die Struktur der Zwischendarstellung für das Zustandsdiagramm

4. Bewertung Anhand einer C++ Steuerungssoftware 4.1

Das allgemeine Sequenzdiagramm

Die Zwischendarstellung lässt sich für das Sequenzdiagramm einfach erstellen. Durch die Speicherung der Daten in einer Tabelle für jede Klasse können die benötigten Teilsequenzen schnell gefunden werden. Durch das Weglassen von Zuweisungen ohne Methodenaufruf kann die Größe der Teilsequenzen noch weiter verringert werden. Während der Auswertung für das Sequenzdiagramm muss keine aufgerufene Methode bekannt sein. Nur die von einem Werkzeug erstellte Klassendefinition des untersuchten Objektes wird zur Unterscheidung von objektinternen Methoden und Bibliotheksfunktionen benötigt. Die Auswertung der Zwischendarstellung sorgt für ein größeres Datenaufkommen. Durch die Schachtelung können die Teilsequenzen für einige Methoden häufiger eingefügt werden. Ein Problem der Schachtelung ist der rekursiven Methodenaufrufe. Der rekursive Methodenaufruf wird den Algorithmus der Schachtelung in eine Endlosschleife führen. Abhilfe ist ein Stapelspeicher, wo die Methodennamen und Objektnamen abgelegt werden. Vor dem einfügen einer Teilsequenz muss dann überprüft werden, ob die Methode nicht schon aufgerufen wurde. Wurde eine Teilsequenz abgearbeitet, wird die oberste Methode mit zugehörigem Objekt wieder weggenommen. Ist kein rekursiver Methodenaufruf in der Software enthalten wird der Algorithmus zu einem definierten Ende kommen. Wird in der Software ein Objekt dynamisch gebunden, so kann einem Methodenaufruf an dieses Objekt keine eindeutige Klasse zugeordnet werden. In einem solchen Fall muss das Objekt bis zur Erzeugung zurückverfolgt werden. Eine Möglichkeit das dynamische Binden einzubeziehen ist die gesonderte Aufnahme von Objekten, die innerhalb einer Verzweigungsstruktur erzeugt werden. Wird dieses Objekt später angesprochen, so muss die Verzweigungsstruktur eingesetzt werden. Für jeden Programmpfad kann dann dem Objekt die entsprechende Klasse zugeordnet werden. 4.2

Das Zustandsdiagramm

Das Datenaufkommen für das Zustandsdiagramm kann sehr groß werden. Dafür ist nicht nur die Programmkomplexität, sondern auch der Programmierstil entscheidend. Durch viele Verzweigungen wächst der Baum exponentiell, falls die Verzweigungen nicht direkt während der Auswertung vereinfacht werden können. Für ein solches Datenaufkommen war bei der Steuerungssoftware eine doppelt verwendete switch Anweisung verantwortlich. Die switch Anweisung wurde in verschiedenen Methoden, jedoch auf die selbe Variable durchgeführt. Die Variable wurde als Parameter übergeben. Der Methodenaufruf wurde in jeder case Anweisung extra durchgeführt und hat dadurch zu einer Datenexplosion geführt. Die 43 Zeilen Code ergaben in dem Zustandsbaum 382 Zweige und insgesamt 72 Endzustände. Damit wird ein weiteres Problem offensichtlich. Die gefundenen Endzustände sind nicht optimal. Für die Optimierung müssen die Zustände auf unnötige Redundanz untersucht und zusammengefaßt werden. Probleme kann es geben, wenn eine aufgerufene Methode noch nicht untersucht wurde. Eine Möglichkeit wäre, die Auswertung zu diesem Zeitpunkt einzuschieben, um die Attributsänderungen festzuhalten und dann mit der ursprünglichen Methode fortzufahren. Wie für das Sequenzdiagramm müssen rekursive Methodenaufrufe durch einen Stapelspeicher aufgelöst werden. Die zweite Möglichkeit ist, im Falle einer Zuweisung, den Gesamtbereich der Variablen einzusetzen. Die Steuerungssoftware hat eine kritische Parameterübergabe. Ein Parameter wurde von der aufgerufenen Methode als Referenz entgegen genommen und verändert. Übergeben wurde ein Attribut des aufrufenden Objektes. Diese Übergabe als Referenz hat gegen das Prinzip der Datenkapselung verstoßen. Das Attribut des aufrufenden Objektes kann verändert werden, ohne die Schnittstelle zu diesem Attribut zu verwenden. Diese referenzierte Parameterübergabe muss als eine mögliche Zustandsänderung gewertet werden und wird nicht sicher erkannt. 4.3

Beispiel: Station Bearbeiten

Die Station Bearbeiten ist ein abgeschlossener Teil der Steuerungssoftware. Sie besteht aus ca. 850 Zeilen Code und den sechs Klassen Drehtisch, Prüfzylinder, Spannzylinder, Bohrmaschine, Bearbeitungsstation und Kommunikation. Die Zwischendarstellung für das allgemeine Sequenzdiagramm besteht aus 131 Zeilen aufgeteilt in sechs Tabellen. Die Enddarstellung für das allgemeine Sequenzdiagramm hat 233 Zeilen. Die Station

Bearbeiten enthält keine rekursiven Methodenaufrufe. Der größte Teil der Kommunikation wurde von der Funktion „main“gesteuert. Die Zwischendarstellung für das Zustandsdiagramm besteht aus 238 Zeilen. Die einzelnen Objekte haben maximal zwei ganzzahlige Attribute. Die Tabelle 3 zeigt die einzelnen Objekte und die zugehörige Anzahl an gefundenen Zuständen. Das „+1“ in der Spalte Zustände soll den undefinierten Anfangszustand andeuten. Objekt

Anzahl Zustände

Drehtisch

12+1

Prüfzylinder

6+1

Spannzylinder

6+1

Bohrmaschine

8+1

Bearbeitungsstation

4+1

Kommunikation

1

Tabelle 3: Die Objekte der Station Bearbeiten und ihre Zustände

5. Zusammenfassung Abschließend kann gesagt werden, dass der Ansatz ein erster Schritt ist, aus objektorientierter Software eine Verhaltensbeschreibung zu gewinnen. Die Beschreibung wird in Form eines allgemeinen Sequenzdiagramms und den Zuständen und Zustandsübergängen angegeben. Durch die Miteinbeziehung der Kontrollflusselemente in das allgemeine Sequenzdiagramm enthält es alle möglichen Szenarien. Aus den Zuständen und Zustandsübergängen können die Zustandsdiagramme für die Objekte erstellt werden. Die für die Auswertung notwendigen Programmkonstrukte sind Methodenaufrufe, Schleifen und Verzweigungen. Es gibt noch Probleme, die weitergehend untersucht und gelöst werden müssen. Eine Lösungsmöglichkeit für die rekursiven Methodenaufrufe wurde bereits gegeben. Bisher wurden auch nur Zahlen als Attribute beachtet. Zur Erweiterung des Konzepts wäre eine Betrachtung weiterer Attributstypen notwendig. Als Ausblick kann das Konzept für weitere Programmkonstrukte untersucht werden und damit verbessert werden. Wichtige Konstrukte sind die Zeiger und Referenzen, die zum Beispiel C++ von C geerbt hat. Zu weiteren Programmkonstruktionen, die untersucht werden müssen, gehört auch der rekursive Methodenaufruf. Die Ausdehnung der Attributstypen auf Objekte und zusammengesetzte Datentypen, wie zum Beispiel Container [5], ist eine weitere notwendige Erweiterung des Konzepts. Die Kommentare, die bei der Entwicklung in den Code eingefügt wurden, sind für das Programmverstehen ebenfalls von Bedeutung [6]. Wie Kommentare in diesem Konzept weiter verwendet werden können, ist zu untersuchen. Weitere Vorgänge, die die Software erst zur Laufzeit beeinflussen, wurden bisher nicht berücksichtigt. Das Konzept existiert bisher nur in der Theorie. Die Umsetzung des Konzepts in einen Prototypen steht noch aus.

6. Referenzen [1] [2] [3]

[4] [5] [6]

Unified Modeling Language – UML - Notation Guide version 1.1, –Rational Software Corporation, Santa Clara, CA, http://www.rational.com, 1998. Oesterreich, B.: Objektorientierte Softwareentwicklung –Oldenbourg 3. Auflage 1997 Nüssle, F.: Überarbeitung einer Steuerungssoftware und Erstellung eines Visualisierungsmoduls für die Anlage ‚Verteilen, Prüfen, Bearbeiten und Lagern‘ –2. Semesterarbeit am Institut für Automatisierungsund Softwaretechnik, Juni 1995 Czerwinski, M.: Automatisierung der MPS-Anlage (Festo) mit CAN-Ankopplung unter C/QNX –1. Semesterarbeit am Institut für Automatisierungs- und Softwaretechnik, Juni 1994 Batory, D.; Thomas, J.; Sirkin, M.: Reengineering a Complex Application Using a Scalable Data Structure Compiler –Departement of Computer Science at the University of Texas at Austin, 1994 Bird, P. L.; Seidl, F. A.: Reengineering Legacy C and C++ Applications –Genitor white paper, June 1998

Suggest Documents