chevron_left
chevron_right

Wenn sich die Software selbst entwickelt

In allen Bereichen unseres Lebens begegnen uns Modelle, die einen bestimmten Sachverhalt vereinfacht beschreiben. Auch im Softwareentwicklungsprozess sind Modelle von zentraler Bedeutung. Durch eine geeignete Modellierung und die entsprechenden Werkzeuge lassen sich Modelle in Quellcode umsetzen. Das Geschieht automatisch und berücksichtigt auch Änderungen.

 

Die Anforderungen an die moderne Softwareentwicklung sind sehr vielseitig. Wiederverwendbarkeit, Wartbarkeit, Testbarkeit und eine hohe Performance sind nur einige Punkte, welche die Software oder vielmehr deren Quellcode mitbringen soll. Die Unterstützung verschiedener Zielsysteme sowie die Vielfalt von Programmiersprachen kommen erschwerend dazu. Grundsätzlich lässt sich eine Software als Menge von Komponenten mit bestimmten Eigenschaften abbilden. Diese Komponenten stehen in einer bestimmten Beziehung zueinander und interagieren miteinander. In welcher Programmiersprache sie geschrieben sind, spielt keine Rolle. Gemeinsam bleibt ihnen aber, dass die Komponenten und ihre Interaktionen mit einer geeigneten Abstraktion beschrieben werden können. Oft bringen Programmiersprachen diese Abstraktion nicht selbst mit und es werden zusätzlich Modellierungssprachen erschaffen, um dies abzudecken.

Generatoren erzeugen Quellcode direkt aus dem Modell

Ein Beispiel einer universellen Modellierungssprache ist die Unified Modeling Language, kurz UML, welche einen standardisierten Weg bietet, das Design eines Systems zu visualisieren. Es gibt aber auch Modellierungssprachen, welche auf einen Gegenstandsbereich (Domäne) zugeschnitten sind. Man spricht dann von sogenannten domänenspezifischen Sprachen, kurz DSL. Der eigentliche Quellcode wird mithilfe von Codegeneratoren und Interpretern automatisch aus dem Modell erzeugt. Wie beispielswiese aus einem UML-Klassendiagramm der entsprechende Java-Quellcode entsteht.

Auch auf andere Programmiersprachen anwendbar

Durch die höhere Abstraktion können Problemstellungen und Konzepte einfacher festgehalten und innerhalb des Entwicklerteams klar kommuniziert werden. Auch die Weiterentwicklung der Software wird durch die klaren Grenzen und die Trennung von der technischen Ebene erleichtert. Da nicht jede Code-Zeile getestet werden muss, lässt sich auch der Testaufwand verringern. Ein weiterer Vorteil ist die Wiederverwendbarkeit des Modells sowie dessen Anwendung auf andere Programmiersprachen. Auch kann die Geschwindigkeit von Code-Fragmenten gesteigert werden, da der generierte Quellcode an sich nicht wartbar oder verständlich sein muss.

Modellgetrieben zum Erfolg

Wann bringt ein modellgetriebener Entwicklungsansatz den grössten Erfolg? Der Initialaufwand, der mit der Entwicklung der domainspezifischen Sprache und dem Erstellen der Codegeneratoren (Templates) einhergeht, darf nicht unterschätzt werden. Vor allem in komplexen Systemen steigt dieser erheblich. Zudem sind meistens nur Teilsysteme oder Komponenten modelliert, die noch um weitere Funktionen ergänzt werden müssen, oder aber noch in das Gesamtsystem zu integrieren sind. Dem Entwickler stehen für die Modellierung eine Vielzahl von Programmen zur Verfügung. Neben spezialisierten Werkzeugen, die meist nur eine Funktion des Entwicklungsprozesses abdecken, gibt es integrierte Entwicklungsumgebungen, die von der Modellierung über Codegeneration bis zu Eingabevalidierung und Synchronisation der verschiedenen Modelle alles bieten. Ein Beispiel einer solchen Entwicklungsumgebung ist Actifsource der Firma actifsource GmbH. Es ist als Plug-in für die populäre Eclipse IDE erhältlich.

Beispiel: Zustandsmaschine

Wohl jeder Softwareentwickler hat schon mal eine Zustandsmaschine programmiert. Auch wenn dies eine schöne Aufgabe mit einem grossen Lerneffekt ist, so wird sie mit der Zeit monoton. Auch die Weiterentwicklung durch hinzufügen von zusätzlich Zuständen ist eher mühsam und fehleranfällig. Als Beispiel für modellgetriebene Softwareentwicklung wird eine Zustandsmaschine mit Actifsource erstellt.

Zuerst wird das generische Domain-Modell mit dem graphischen Editor definiert. Es beschreibt die Struktur einer allgemeinen Zustandsmaschine. Im Beispiel hat diese also mindestens einen Zustand und ein Ereignis, auf das man reagieren kann. Zudem kann ein Zustand eine Transition haben und ein Zustand kann Ziel einer Transition sein. Als nächstes erstellt der Programmierer die eigentliche Zustandsmaschine, hier im Beispiel mit drei Zuständen und zwei Ereignissen.

Der Programmcode ist immer auf dem aktuellen Stand

Um für die modellierte Zustandsmaschine Programmcode zu generieren, wird ein Template erstellt. Dieser ganze Prozess mag nun für diese einfache Zustandsmaschine nach viel Arbeit aussehen, aber das Domain-Modell und das Template für C++-Code sind für alle zukünftigen Zustandsmaschinen wieder verwendbar. Auch können im Editor auf einfache Weise neue Zustände, Ereignisse und Transitionen ergänzt werden, woraus der Generator immer den aktuellen Programmcode erzeugt.

Insbesondere Tests für Software haben die Eigenschaft, dass eine Änderung im Code ständig Anpassungen in den Tests nach sich zieht. Natürlich lassen sich auf die beschriebene Art auch Tests und Dokumentationen automatisch erzeugen und so die Testabdeckung und der Aufwand minimieren.

Datenmodell für Embedded Firmware

Eine weitere Verwendung von Modellgetriebener Softwareentwicklung zeigt folgendes Beispiel: Zwei Embedded-Systeme teilen sich einen Datensatz mit Parametern für die Konfiguration und die aktuellen Prozessdaten. Dabei kann jede Seite Daten ändern und geänderte Daten empfangen. Zudem gibt es die Option eines der Systeme mit einem Computer zu verbinden, um die aktuellen Daten anzuzeigen oder auch zu überschreiben. Während der Entwicklung waren der volle Umfang und die genauen Wertebereiche der einzelnen Datenpunkte noch nicht vollständig definiert. Um auf Änderungen des Datensatzes vorbereitet zu sein, lohnt es sich hier einen modellgetrieben Ansatz zu verfolgen. Weiter kommt noch hinzu, dass das gleiche Datenmodell in drei verschiedenen Programmiersprachen umgesetzt wurde (C, C++ und Java). Änderungen in den jeweiligen Quellcodes manuell anzupassen, wäre mühsam und fehleranfällig.

Der Mehraufwand am Anfang macht sich bezahlt

Die Entwickler erstellten also ein Modell, wie sich ein solcher Datensatz zusammenstellt und welche Typen von Datenpunkten (Enumerator, Integer, Float usw.) mit welchen Eigenschaften er beinhaltet. So können zum Beispiel Callback-Funktionen Registriert werden, wenn sich ein Wert geändert hat. Von diesem Modell wurde ein realer Datensatz abgleitet. Durch die Verwendung verschiedener Templates haben die Programmierer für jede der verwendeten Programmiersprachen daraus den jeweiligen Quellcode generiert. Auch die Synchronisation der einzelnen Daten über einen beliebigen physikalischen Kanal bildete das Modell ab.

Dieses System haben die Entwickler mithilfe von Actifsource erfolgreich umgesetzt. Der anfängliche Mehraufwand für die modellgetriebene Entwicklung konnte durch die Flexibilität bei der Erweiterungen und der aktiven Wiederverwendung in anderen Projekten mehr als kompensiert werden.

Infoservice


Actifsource GmbH
Täfernstrasse 37, 5405 Baden-Dättwil
Tel. 056 250 40 00