Anbieter zum Thema
Include-Beziehungen und Component-Based Design
Teile und herrsche ist der meist eingesetzte Engineering-Schritt, Komplexität zu begegnen. In C wird dem mit Modulen und Funktionen begegnet. Jedes Mal, wenn ein System in kleinere Komponenten geteilt wird, entstehen Schnittstellen. Ein Teil der Komplexität wird dabei auf die Beziehungsebenen verschoben. In ANSI C wird die Struktur der Beziehungen durch Include-Beziehungen repräsentiert. Diese Struktur ist jedoch nicht explizit zu sehen und lästig zu managen, was dazu führt, dass in den meisten Projekten über eine globale Include-Struktur alles mit allem in Beziehung steht. Das führt dazu, dass auch alles mit allem kommunizieren kann, was zu sogenannten Hidden Links führt. Diese Hidden Links erhöhen bei Änderungen das Risiko für Emergenz (Systeme kommen in nicht gewollte Zustände), und damit zum Fehlverhalten.
In UML können Beziehungsstrukturen ganz gezielt grafisch modelliert werden. Daraus werden eindeutige Include-Beziehungen in C generiert. Wenn ein Programmierer nicht dieser Interface-Struktur folgt wird spätestens der Linker die Arbeit versagen. Das ist eine sehr effiziente Hilfe Hidden Links vorzubeugen. Durch grafische Visualisierung und daraus erzeugten Include-Beziehungen lassen sich sehr effektiv Hidden Links vermeiden, was bei steigender Komplexität weniger häufig zu Emergenz und Disfunktion führt.
Spezifikation und Test-Automatisierung
Die Notation UML besitzt im Gegensatz zu herkömmlichen Hochsprachen wie ANSI C oder C++ Notationselemente, die die Spezifikation von Systemen adressieren (UseCase-, Sequenz- und Timing-Diagramme, Bild 3 und 4). Die Mächtigkeit dieser Diagramme wird häufig unterschätzt. Das liegt auch daran, dass dem Anforderungsmanagement im Allgemeinen nicht besonders viel Aufmerksamkeit geschenkt wird und direkt implementiert wird. Aber spätestens beim Testen werden die eigentlichen Anforderungen benötigt. Gegen was soll denn die Implementation getestet werden?
Also in jedem Projekt wird im eigentlichen Sinn Anforderungsmanagement betrieben. Entweder zum günstigen Zeitpunkt am Anfang des Projektes oder zum weniger günstigen Zeitpunkt am Ende des Projektes, wenn die Tests spezifiziert werden (vorausgesetzt, dass halbwegs ordentlich getestet wird).
Wenn nun die Spezifikation die Quelle der Tests sind, was läge näher, als die Tests zu spezifizieren. Genau das ist z.B. auf Basis von Sequenz-Diagrammen möglich. Zum Beginn eines Projektes dienen sie dazu, sich klar zu machen, wie das System in bestimmten Situationen zu reagieren hat, welche Funktionen es bekommen muss …. Diese Diagramme können in Folge dann sehr einfach dazu dienen, die ersten Implementierungen zu testen. Das Ganze kann sogar automatisiert in der Nacht geschehen (Nightly Tests).
Das Vorgehen kann auch als TDD (Test Driven Development) gesehen werden, was nachweislich Qualität von Software erhöht. Dieses Vorgehen ist auf Basis von UML und geeigneten Werkzeugen sehr viel einfacher möglich, als auf Basis von Hochsprachen. Auf Basis von standardisierten Notationselementen zur Spezifikation von Systemen lassen sich mit geringem Aufwand automatisierte Tests erstellen. Dieses ist die ideale Voraussetzung für Nightly Tests und Test Driven Design als eine der mächtigsten Instrumente zur Qualitätsabsicherung.
Abstraktion und Muster - Contract Based Design
Zustandsmaschinen repräsentieren die Kombination von Mustern und darauf basierender Abstraktion. Die Visualisierung einer simplen Zustandsmaschine mit zwei Zuständen und zwei Zustandsübergängen auf Basis eines Zustand-Diagramms enthält sechs Symbole (zwei für den formal notwendigen Default State). Ein korrespondierender Code mit allen notwendigen Implementierungen würde im simpelsten Fall ca. 200 Zeilen lang sein.
Zum Beispiel stellt das Event Handling mit Event Queue ein Muster dar, das genauen Regeln folgt, welche in der Zustandsmaschine implizit enthalten bzw. berücksichtigt sind. Das Verhalten der Zustandsmaschine lässt sich sehr exakt verstehen, ohne das Kenntnisse über die genauen Implementationen vorhanden sein müssen. Sehr viel wichtiger sind genaue Kenntnisse über die Regeln (Contract), dem dieses Muster folgt.
Es gibt beispielsweise die Regel, dass Events, auf die zum aktuellen Zeitpunkt kein Zustand wartet, weggeschmissen werden. Ansonsten würden sie die Queue blockieren. Das macht durchaus Sinn. Wenn die Regel jedoch nicht bekannt ist und beim Design der Zustandsmaschine nicht berücksichtigt wird, kann es zu Fehlern führen. Umgekehrt ist es genau so: Werhält sich die Implementation des Musters nicht so, wie definiert, führt auch das zu Fehlverhalten. Leider wird die Notwendigkeit, die Spezifikation der Muster sehr gut zu kennen, häufig nicht ernst genug genommen und Muster werden nicht derart verwandt, wie sie ursprünglich gedacht waren.
Wie mächtig Muster sind, kann sehr deutlich erkannt werden, würde der generierte Code aus folgenden beiden Zustandsmaschinen betrachtet. Hier ist nicht nur Code hinzugekommen, sondern es bleibt im wahrsten Sinn des Wortes keine Zeile Code mehr auf der anderen. Würde man dieselbe Änderung auf Code-Ebene durchführen, würden wahrscheinlich aus Bequemlichkeit den Zuständen Rucksäcke verpasst werden. Das würde sich jedoch nachteilig, sowohl auf Codegröße, Laufzeit und Verstehbarkeit auswirken und die Komplexität unnötig erhöhen. Einem Codegenerator ist der Aufwand der Änderung egal. Er erzeugt in Sekunden-Bruchteilen wieder neuen sauberen Code.
Auf Basis von Abstraktion und Mustern lässt sich Software sehr viel einfacher und vergleichsweise sicherer verstehen, ändern und erweitern, als auf Basis von C-Code. Darüber hinaus lässt sich die inhärente Qualität bei Änderungen und Erweiterungen hoch halten.
Frühe Simulation - Frontloading
Bleiben wir gleich bei der vorherigen Zustandsmaschine. Sehr häufig wird Genauigkeit (Exaktheit) mit Detailliertheit verwechselt. Immer wieder höre ich, dass eine frühe Simulation auf Basis von UML nicht möglich ist, da ja erst simuliert werden kann, wenn das Modell mit ausreichend Details angereichert wurde. Das ist schlicht falsch. Das Verhalten obiger Zustandsmaschine kann genau in diesem Grad der Detaillierung bereits simuliert werden. Lediglich die Namen der Events müssen derart definiert werden, dass sie kompilierbar sind (Den gültigen Symbol-Definitionen der zukünftigen Action Language folgen).
Dann kann die Logik der Zustandsmaschine simuliert werden. Aber es geht noch weiter, erinnern Sie sich an Spezifikation auf Basis von Sequenz-Diagrammen. Schon zu diesem Zeitpunkt kann getestet werden, ob die Logik der Zustandsmaschine der Definition der Sequenzen entspricht und diese einhält.
Artikelfiles und Artikellinks
(ID:44117894)