
Reverse Engineering von Entwurfsmustern
Dokumentinformationen
Autor | Sebastian Naumann |
instructor | Prof. Dr.-Ing. habil. Ilka Philippow |
Schule | Technische Universität Ilmenau, Fakultät für Informatik und Automatisierung |
Fachrichtung | Informatik |
Dokumenttyp | Diplomarbeit |
Ort | Ilmenau |
Sprache | German |
Format | |
Größe | 1.74 MB |
Zusammenfassung
I.Das Problem Manuelles Auffinden von Entwurfsmustern
Das Verständnis von Softwaresystemen, insbesondere bei der Wartung und Weiterentwicklung, ist oft durch fehlende oder unzureichende Dokumentation erschwert. Das manuelle Auffinden von Entwurfsmustern (Design Patterns) im Quellcode ist mühsam und fehleranfällig. Die Kenntnis von Entwurfsmustern verbessert jedoch deutlich das Programmverstehen und beschleunigt den Entwicklungsprozess. Das Buch "Entwurfsmuster" von Gamma et al. ([Gamma+96]) gilt als Quasi-Standard, dessen Muster in vielen Softwaresystemen implizit verwendet werden. Eine effiziente automatische Mustersuche ist daher dringend notwendig.
1. Die Herausforderungen des Programmverständnisses
Die Wartung von Softwaresystemen stellt einen erheblichen Kostenfaktor dar. Bevor Änderungen vorgenommen werden können, ist ein tiefes Programmverstehen unerlässlich. Dieses wird jedoch oft durch unzureichende oder veraltete Dokumentation, fehlende Spezifikationen und den Ausfall der ursprünglichen Entwickler erschwert. Der Quellcode bleibt oft als einziges zuverlässiges Dokument übrig. Die Analyse von Quellcode allein, um die Funktionsweise und die zugrundeliegenden Ideen eines Systems zu verstehen, ist jedoch extrem zeitaufwendig und mühsam. Die Gefahr unerwünschter Seiteneffekte durch Änderungen ist ohne umfassendes Verständnis sehr hoch. Wäre das Wissen über die verwendeten Entwurfsmuster explizit im Quellcode dokumentiert, würde dies das Programmverstehen erheblich erleichtern. In der Realität ist dies jedoch selten der Fall; die Information über die Entwurfsmuster ist meist nur implizit vorhanden. Das Buch "Entwurfsmuster" ([Gamma+96]) dient als Quasi-Standard für Entwurfsmuster in der objektorientierten Softwareentwicklung.
2. Die Bedeutung von Entwurfsmustern für das Programmverstehen
Jedes Entwurfsmuster repräsentiert eine spezifische Lösung für ein wiederkehrendes Entwurfsproblem. Es ist bekannt, welchen Zweck ein Muster verfolgt und welche Vor- und Nachteile es mit sich bringt. Die Kenntnis der verwendeten Entwurfsmuster ermöglicht ein schnelleres und tieferes Programmverstehen auf einer abstrakteren Ebene. Ein Entwickler kann die Idee hinter einem Code-Abschnitt sofort erfassen, selbst wenn die reine Klassenstruktur dies nicht direkt offenbart. Experimente bestätigen die Vorteile des Wissens über Entwurfsmuster für das Programmverstehen. Obwohl ein Softwaresystem idealerweise aus vielen ineinandergreifenden Entwurfsmustern bestehen sollte, ist dies in der Praxis eher selten der Fall. Einzelne Entwurfsmuster können jedoch auf bestimmte Eigenschaften des Systems hinweisen (z.B. Adapter, Brücke, Proxy). Die Suche nach Entwurfsmustern im Quellcode ist jedoch für den Menschen aufgrund der Vielgestaltigkeit der Muster sehr schwierig. Programmiersprachen bieten hierfür keine direkte Unterstützung, wodurch die Dokumentation meist auf Kommentare beschränkt bleibt. Ein präzises Wissen über die Entwurfsmuster (Zweck, beteiligte Klassen, Vor- und Nachteile) ist daher unerlässlich.
3. Die Notwendigkeit automatischer Unterstützung
Die manuelle Identifizierung von Entwurfsmustern in großen Softwaresystemen ist für Menschen äußerst schwierig und zeitaufwendig. Die Notwendigkeit von Softwarewerkzeugen zur automatischen Unterstützung wird betont. Die automatische Suche nach Entwurfsmustern ist nicht nur für das Programmverstehen, sondern auch für das Refactoring von Altsystemen und die Neuentwicklung von Softwaresystemen relevant. Ein Software-Werkzeug kann die korrekte Anwendung von Entwurfsmustern überprüfen und den Entwickler bei der Fehlerkorrektur unterstützen. Die unerwartete Entdeckung eines Entwurfsmusters kann zu einem besseren Verständnis des Systems führen. Beispiele zeigen, wie Merkmale für die Suche nach bestimmten Mustern (z.B. Kompositum, Dekorierer) definiert werden können. Die existierenden Werkzeuge zur automatischen Entwurfsmustererkennung weisen jedoch erhebliche Mängel auf. Ein Werkzeug, das alle Muster aus [Gamma+96] zuverlässig findet und gleichzeitig eindeutig definierte Muster sicher identifiziert, fehlt. Die Genauigkeit der bestehenden Ansätze ist oft unzureichend. Die vorliegende Arbeit adressiert diese Defizite durch einen neuen Ansatz.
II.Derzeitiger Stand der automatischen Mustersuche
Bestehende Ansätze zur automatischen Mustersuche zeigen Schwächen. Einige Methoden konzentrieren sich auf minimale Schlüsselmerkmale von Entwurfsmustern, erkennen aber nicht alle Muster aus [Gamma+96]. Andere Ansätze suchen nach vollständigen Übereinstimmungen in der Klassenstruktur, versagen aber bei Varianten und weniger klar definierten Mustern wie der Schablonenmethode. Die Genauigkeit (Präzision) der existierenden Werkzeuge ist oft niedrig. Ein umfassender Ansatz, der alle 23 Entwurfsmuster aus [Gamma+96] zuverlässig identifiziert, fehlt bisher.
1. Mängel bestehender Ansätze zur automatischen Mustersuche
Der aktuelle Stand der automatischen Mustersuche für Entwurfsmuster zeigt erhebliche Defizite. Nur wenige Ansätze können alle 23 Muster aus dem Standardwerk [Gamma+96] zuverlässig identifizieren. Ein Ansatz, der auf Metriken basiert, schafft dies zwar, versagt jedoch bei eindeutig definierten Mustern wie der Schablonenmethode. Eine Gruppe von Arbeiten verwendet Schlüsselmerkmale in der Struktur der Entwurfsmuster, um diese zu identifizieren. Diese Methode funktioniert gut für klar definierte Muster, jedoch sind nicht für alle Entwurfsmuster solche Merkmale definiert. Die erzielte Genauigkeit (Präzision) ist bei den existierenden Ansätzen insgesamt niedrig. Die meisten Ansätze decken nur eine Teilmenge der in [Gamma+96] beschriebenen Entwurfsmuster ab. Es besteht ein Bedarf an einem umfassenderen und genaueren Ansatz zur automatischen Mustersuche, der die Schwächen bestehender Methoden überwindet.
2. Analyse verschiedener Ansätze zur automatischen Mustersuche
Der Abschnitt analysiert verschiedene Ansätze zur automatischen Mustersuche. Eine Gruppe von Ansätzen sucht nach minimalen Schlüsselstrukturen der Entwurfsmuster (DP++, KT, SPOOL), wobei diese Methoden nur einen Teil der Muster abdecken. Eine zweite Gruppe (Pat, IDEA, Mehrstufiger Suchprozess) fokussiert auf vollständige Übereinstimmungen in der Klassenstruktur, was jedoch die Vielgestaltigkeit der Entwurfsmuster nicht ausreichend berücksichtigt. Ein weiterer, nicht implementierter Ansatz schlägt eine flexible Musterdefinition mit Fuzzylogik vor, um die Variabilität der Entwurfsmuster zu adressieren. Der Pattern Wizard charakterisiert Entwurfsmuster anhand von Metriken und vergleicht diese, findet zwar alle Muster aus [Gamma+96], versagt aber beim eindeutig definierten Schablonenmethoden-Muster. Schließlich wird eine induktive Methode (BACKDOOR) für die manuelle Suche vorgestellt, die jedoch keine direkte Umsetzung in ein Software-Werkzeug erlaubt. Die niedrige Präzisionsrate der bestehenden Ansätze und die unvollständige Abdeckung der Entwurfsmuster aus [Gamma+96] unterstreichen die Notwendigkeit eines verbesserten Ansatzes zur automatischen Mustersuche.
3. Zusammenfassung der Defizite und Formulierung der Problemstellung
Die Analyse der bestehenden Ansätze zur automatischen Mustersuche zeigt deutliche Defizite auf: Nur der Pattern Wizard findet alle Muster aus [Gamma+96], versagt aber bei eindeutig definierten Mustern wie der Schablonenmethode. Ansätze, die auf minimalen Schlüsselmerkmalen basieren, definieren diese nicht für alle Entwurfsmuster. Die erreichte Präzision ist bei allen Ansätzen niedrig. Es ist nicht möglich, die verschiedenen Ansätze zu kombinieren, um eine umfassende Suchstrategie für alle Entwurfsmuster zu erhalten. Aus diesen Mängeln wird eine präzisierte Problemstellung abgeleitet: Ein neuer Ansatz muss erstens alle Entwurfsmuster aus [Gamma+96] abdecken, zweitens eindeutig definierte Muster sicher identifizieren und drittens die Präzision der Mustersuche deutlich verbessern. Diese Anforderungen bilden die Grundlage für die Entwicklung des eigenen Ansatzes, der in den folgenden Abschnitten detailliert beschrieben wird.
III.Ein neuer Ansatz zur Mustersuche
Dieser Forschungsansatz erweitert bestehende Methoden, indem er für jedes der 23 Entwurfsmuster aus [Gamma+96] spezifische Suchstrategien und Schlüsselmerkmale definiert. Neben dem Vorhandensein bestimmter Merkmale werden auch Merkmale berücksichtigt, die nicht vorhanden sein sollten, um Fehlklassifikationen zu reduzieren. Dieser Ansatz zielt auf eine vollständige Abdeckung aller Muster, die sichere Identifizierung eindeutig definierter Muster (z.B. Schablonenmethode, Fabrikmethode) und eine höhere Präzision ab. Die entwickelten Algorithmen werden mit einer Laufzeitkomplexität bewertet (z.B. O(n), O(n²)).
1. Grundlage des neuen Ansatzes Lernfähigkeit von Softwareentwicklern
Der neue Ansatz basiert auf der Beobachtung, dass Softwareentwickler in der Lage sind, Entwurfsmuster in Code-Fragmenten zuverlässig zu erkennen, auch ohne explizite Dokumentation. Die Schwierigkeit liegt in der Suche nach diesen Mustern in großen, komplexen Softwaresystemen. Daher wird angenommen, dass Entwurfsmuster spezifische, oft feingranulare Schlüsselmerkmale besitzen, die ihre Identifizierung ermöglichen. Diese Merkmale können sowohl aus der Struktur (z.B. Klassenbeziehungen) als auch aus den Namen der Klassen abgeleitet werden (z.B. Suffix „-Fabrik“ für das Abstrakte Fabrik-Muster). Der Ansatz geht davon aus, dass ein Computerprogramm, ähnlich einem Softwareentwickler, diese Merkmale identifizieren kann. Die Herausforderung besteht darin, die Suche effizient zu gestalten, um eine exponentielle Zeitkomplexität bei der Überprüfung aller möglichen Teilmengen eines Systems zu vermeiden. Der Ansatz greift die Idee von Brown, Bansiya, Keller, Schauer, Robitaille und Pagé auf, nach bestimmten Schlüsselmerkmalen zu suchen, erweitert diese aber deutlich.
2. Der erweiterte Ansatz Positive und negative Schlüsselmerkmale
Im Gegensatz zu bisherigen Ansätzen, die sich auf das Vorhandensein von Schlüsselmerkmalen konzentrieren, berücksichtigt dieser Ansatz zusätzlich Merkmale, die nicht vorhanden sein sollten. Diese „negativen“ Schlüsselmerkmale helfen, falsch positive Ergebnisse zu reduzieren und die Präzision der Mustersuche zu erhöhen. Für jedes der 23 Entwurfsmuster aus [Gamma+96] wird eine eigene Suchstrategie definiert, die sowohl positive als auch negative Merkmale umfasst. Die Berücksichtigung von negativen Merkmalen ist ein Novum und unterscheidet diesen Ansatz von bisherigen Ansätzen. Die Suche erfolgt durch die Überprüfung beider Merkmalstypen im zu analysierenden Softwaresystem. Die im folgenden Abschnitt detailliert beschriebenen Merkmale für jedes Muster bilden die Grundlage für die entwickelten Algorithmen und Suchstrategien. Die Algorithmen werden hinsichtlich ihrer Komplexität (z.B. O(n), O(n²)) bewertet.
3. Bewertung und Vergleich mit bestehenden Ansätzen
Der vorgeschlagene Ansatz zur automatischen Mustersuche unterscheidet sich deutlich von bestehenden Ansätzen, die oft nur eine Teilmenge der Entwurfsmuster aus [Gamma+96] abdecken. Im Gegensatz zu Ansätzen wie dem von Kim und Boldyreff [Kim+00], der beim eindeutig definierten Schablonenmethoden-Muster versagt, zielt dieser Ansatz auf eine vollständige Abdeckung aller 23 Muster ab. Die Verwendung der gleichen Suchstrategie wie bei Keller et al. [Keller+99] ermöglicht die zuverlässige Identifizierung eindeutig definierter Muster wie der Schablonenmethode und der Fabrikmethode. Durch die Angabe von Algorithmen für jedes Muster wird die praktische Umsetzbarkeit der Schlüsselmerkmale belegt. Die prototypische Implementierung in Kapitel 4 bestätigt die Funktionsfähigkeit des Ansatzes. Der Ansatz erfüllt die in Kapitel 2 definierten Anforderungen: vollständige Abdeckung der Entwurfsmuster, zuverlässige Identifizierung eindeutig definierter Muster und eine signifikante Steigerung der Präzision.
IV.Prototypische Implementierung und Ergebnisse
Eine prototypische Implementierung des Ansatzes wurde mit dem CASE-Tool Rational Rose durchgeführt. Die Quellcode-Analyse erfolgte mittels des Rational Rose C++ Analyzers, der ein UML-Klassendiagramm erzeugt. Die Algorithmen zur Entwurfsmustererkennung wurden in der Rational Rose Skriptsprache implementiert. Die Ergebnisse zeigen, dass der Ansatz alle Entwurfsmuster abdecken kann, im Gegensatz zu bisherigen Ansätzen, die oft nur Teilmengen behandeln. Rational Rose zeigte jedoch Einschränkungen bei der Quellcode-Analyse, insbesondere beim Erkennen von Methodenaufrufen, was die Genauigkeit der Mustersuche beeinflusst.
1. Umsetzung mit Rational Rose Methoden und Werkzeuge
Die prototypische Umsetzung des neuen Ansatzes zur Entwurfsmustererkennung erfolgte mit dem CASE-Tool Rational Rose. Ein C++ Quellcode-Programm wurde zunächst mit dem Rational Rose C++ Analyzer analysiert und in ein UML-Klassendiagramm umgewandelt. Die in Kapitel 3 beschriebenen Algorithmen zur Mustersuche wurden dann in der Rational Rose Skriptsprache (Rational Rose Script) implementiert und auf dem generierten Klassendiagramm angewendet. Bei der Quellcode-Analyse wird das Rose Extensibility Interface genutzt, um auf die Modellelemente (Klassen, Eigenschaften etc.) zuzugreifen. Eine alternative Methode, der Zugriff über Rational Rose Automation, wurde aufgrund fehlender Dokumentation verworfen. Wird ein Entwurfsmuster gefunden, generiert der Algorithmus eine Menge der beteiligten Klassen und übergibt diese an ein Modul zur Darstellung der gefundenen Muster, sowohl einzeln als auch im Kontext des gesamten Systems, zur Unterstützung des Programmverständnisses.
2. Ergebnisse und Einschränkungen von Rational Rose
Die Implementierung zeigt, dass Rational Rose nicht optimal für die Suche nach Entwurfsmustern geeignet ist. Einige wichtige Merkmale, die für eine zuverlässige Mustersuche unerlässlich sind, wie z.B. das Erkennen von Methodenaufrufen, werden von Rational Rose nicht ausreichend unterstützt. Für zwei Muster (Singleton und Interpreter), die von diesen Einschränkungen nicht betroffen sind, wurde eine vollständige Implementierung der Algorithmen durchgeführt. Für das Kompositum-Muster mussten bei der Überprüfung der Merkmale Kompromisse eingegangen werden. Die Ergebnisse zeigen jedoch, dass der Ansatz prinzipiell in der Lage ist, alle Entwurfsmuster zu identifizieren, im Gegensatz zu bisherigen Ansätzen. Die Darstellung der gefundenen Entwurfsmuster wird im Kontext des gesamten Systems ermöglicht, um das Programmverstehen zu verbessern. Die Einschränkungen von Rational Rose bezüglich der Quellcode-Analyse werden als zukünftige Verbesserungs- und Erweiterungsmöglichkeiten betrachtet, z.B. durch die Entwicklung zusätzlicher Skripte zur automatischen Erkennung wichtiger Merkmale wie Aggregationsbeziehungen.
3. Fazit zur prototypischen Implementierung
Die prototypische Umsetzung verdeutlicht die prinzipielle Funktionsfähigkeit des vorgeschlagenen Ansatzes zur automatischen Mustersuche. Trotz der Einschränkungen von Rational Rose bei der Quellcode-Analyse konnte gezeigt werden, dass der Ansatz im Prinzip alle Entwurfsmuster aus [Gamma+96] identifizieren kann. Die Implementierung der Algorithmen für Singleton und Interpreter verlief erfolgreich, während beim Kompositum-Muster Anpassungen notwendig waren. Die Ergebnisse unterstreichen die Notwendigkeit einer verbesserten Quellcode-Analyse in zukünftigen Implementierungen. Die Möglichkeit der geeigneten Darstellung gefundener Entwurfsmuster zur Unterstützung des Programmverständnisses wurde aufgezeigt. Die Autoren der in Kapitel 2 vorgestellten Ansätze betonen übereinstimmend die Notwendigkeit einer manuellen Nachprüfung der Ergebnisse durch Softwareentwickler. Eine explizite Dokumentation von Entwurfsmustern im Quellcode wird daher empfohlen, idealerweise durch Sprachkonstrukte, die derzeit noch nicht in gängigen Programmiersprachen vorhanden sind.
V.Fazit und Ausblick
Die automatische Suche nach Entwurfsmustern kann das Programmverstehen erheblich verbessern, ist aber nicht fehlerfrei. Eine manuelle Überprüfung der Ergebnisse durch Softwareentwickler bleibt notwendig. Die vorgestellte Methode bietet einen verbesserten Ansatz zur automatischen Mustersuche, der alle Entwurfsmuster aus [Gamma+96] berücksichtigt und eine höhere Präzision anstrebt. Zukünftige Arbeiten könnten sich auf die Verbesserung der Quellcode-Analyse und die Integration in bestehende Entwicklungsumgebungen konzentrieren.
1. Zusammenfassung der Ergebnisse der prototypischen Implementierung
Die prototypische Umsetzung des neuen Ansatzes zur automatischen Mustersuche mit Rational Rose zeigte, dass der Ansatz prinzipiell in der Lage ist, alle 23 Entwurfsmuster aus [Gamma+96] zu identifizieren. Dies im Gegensatz zu vorherigen Ansätzen, die nur Teilmengen abdecken konnten. Die Implementierung nutzte den Rational Rose C++ Analyzer zur Quellcode-Analyse und erzeugte ein UML-Klassendiagramm. Die entwickelten Algorithmen wurden in Rational Rose Script umgesetzt. Für die Muster Singleton und Interpreter funktionierte die Implementierung ohne größere Probleme. Beim Kompositum-Muster waren jedoch Anpassungen aufgrund von Einschränkungen in Rational Rose notwendig. Die Ergebnisse bestätigen die Umsetzbarkeit des Ansatzes und die Eignung der definierten Schlüsselmerkmale. Die Darstellung der gefundenen Entwurfsmuster im Kontext des gesamten Systems wurde erfolgreich demonstriert, was das Programmverstehen unterstützen soll.
2. Herausforderungen und Limitationen der Rational Rose Implementierung
Die Implementierung mit Rational Rose offenbarte jedoch auch Einschränkungen des Werkzeugs für die automatische Mustersuche. Rational Rose weist Defizite in der Quellcode-Analyse auf, insbesondere beim Erkennen von Methodenaufrufen, was für die Identifizierung einiger Entwurfsmuster essentiell ist. Diese Limitationen führten dazu, dass für einige Muster Kompromisse bei der Überprüfung der Schlüsselmerkmale gemacht werden mussten. Die manuelle Anpassung von Rational Rose wäre zwar möglich, ist aber sehr aufwendig. Eine bessere Lösung wäre die Entwicklung zusätzlicher Skripte, die die fehlenden Funktionen automatisieren. Die Erweiterung von Rational Rose wird daher als zukünftige Aufgabe identifiziert. Die Tatsache, dass selbst mit dem verbesserten Ansatz eine manuelle Überprüfung durch einen Softwareentwickler notwendig bleibt, unterstreicht die Komplexität der automatischen Mustersuche.
3. Ausblick Zukünftige Forschungsarbeiten und Verbesserungen
Die automatische Suche nach Entwurfsmustern bleibt eine Herausforderung, da eine hundertprozentige Genauigkeit nicht garantiert werden kann. Eine abschließende Überprüfung durch einen Softwareentwickler ist daher unerlässlich. Zukünftige Arbeiten könnten sich auf die Verbesserung der Quellcode-Analyse konzentrieren, um die Genauigkeit der Mustersuche zu steigern. Die Integration des Ansatzes in bestehende Entwicklungsumgebungen ist ein weiterer wichtiger Aspekt. Die Notwendigkeit einer expliziten Dokumentation von Entwurfsmustern im Quellcode wird hervorgehoben, wobei eine feste Verankerung im Quellcode wünschenswert, aber derzeit in gängigen Programmiersprachen nicht vorhanden ist. OpenJava, eine Erweiterung von Java, wird als mögliche Alternative erwähnt, die ein Präcompiling zur Einbindung von Metadaten nutzt. Die vorgestellte Methode liefert einen verbesserten Ansatz, jedoch bleibt die Weiterentwicklung und Verfeinerung der Schlüsselmerkmale sowie die Berücksichtigung weiterer Entwurfsmuster wichtig.