Der moderne Softwareentwicklungsprozess mit UML


Kapitel 5: Code-Generierung


Inhaltsverzeichnis

Dieses Buch ist unter einer Creative Commons-Lizenz lizensiert.


5.1 Allgemeines

Code-Generierung ist produktabhängig

Unter Code-Generierung versteht man den Prozess, der UML-Diagramme in Quellcode überführt. Dieser Prozess ist notwendig, da UML-Diagramme ja lediglich Ausdruck eines Modells Ihrer Software sind. Irgendwann wollen Sie aber natürlich die Software erstellen, für die Sie lauter UML-Diagramme gezeichnet haben. Das heißt, die UML-Diagramme müssen irgendwie in Quellcode übersetzt werden. Dieser Vorgang kann natürlich manuell vorgenommen werden - die automatische Übersetzung in Quellcode wird aber für gewöhnlich vorgezogen, nimmt sie doch viel Arbeit ab.

Die UML als programmiersprachen- und plattformunabhängige Modellierungssprache bietet grundsätzlich die Möglichkeit, UML-Diagramme per Knopfdruck in Quellcode einer beliebigen Programmiersprache zu überführen. Eine automatische Übersetzung ist jedoch nur möglich, wenn den geometrischen Formen der UML-Diagramme Schlüsselwörter oder Konzepte einer Programmiersprache gegenüberstehen. Wie soll aber zum Beispiel grundsätzlich eine Aktion in Code übersetzt werden, wie sie in Aktivitätsdiagrammen zum Einsatz kommt?

Auch die Tatsache, dass die UML als Modellierungssprache in Diagrammen wichtige Aspekte hervorhebt und unwichtige Aspekte ignoriert, ist für die Code-Generierung hinderlich. Wie soll Quellcode automatisch erstellt werden, wenn bestimmte Aspekte der Software in keinem Diagramm vorkommen, weil sie aus Sicht des Modellierers jeweils nicht wichtig genug waren, um in Diagrammen aufgenommen zu werden? Für die Code-Generierung ist es daher unvermeidlich, alles in UML-Diagrammen abzubilden, was später auch tatsächlich im Quellcode benötigt wird. Das verfälscht ein wenig den Sinn und Zweck der UML, da nun wirklich alle Details einer Software im Modell erwähnt werden müssen.

Der UML-Standard gibt auf die Frage, wie ein Modell in Form von UML-Diagrammen in Quellcode überführt werden soll, keine Antwort. Es bleibt also den Herstellern von Modellierungswerkzeugen überlassen, wie UML-Diagramme in Code übersetzt werden. Da also die Übersetzung von UML-Diagrammen in Quellcode produktabhängig ist, kann dieses Kapitel lediglich die Code-Generierung bestimmter Modellierungswerkzeuge vorstellen.


5.2 Qualitätskriterien der Code-Generierung

Vollständigkeit, Unabhängigkeit und Round Trip Engineering

Bevor wir uns die Code-Generierung in der Praxis ansehen, sehen wir uns die Merkmale an, anhand derer eine gute Code-Generierung von einer schlechten Code-Generierung unterschieden werden kann.

  • Die Code-Generierung ist umso besser, je mehr UML-Diagramme und geometrische Formen in UML-Diagrammen in Code übersetzt werden. Wenn Sie viel Zeit für das Erstellen unterschiedlicher UML-Diagramme aufwenden und in den UML-Diagrammen viele unterschiedliche geometrische Formen verwenden, werden Sie enttäuscht sein, wenn bei der Code-Generierung nur ein Teil dessen berücksichtigt wird, was Sie aufwändig in UML-Diagrammen modelliert haben.

  • Die Code-Generierung ist umso besser, je mehr Programmiersprachen und Plattformen unterstützt werden. Die UML als programmiersprachen- und plattformunabhängige Modellierungssprache hat zum Ziel, Ihre Investitionen in die Softwaremodellierung langfristig zu sichern. Wenn das von Ihnen verwendete Modellierungswerkzeug nun aber nur bestimmte Programmiersprachen oder Plattformen unterstützt, steht Ihre Investition auf wackligen Beinen. Im schlimmsten Fall müssen Sie eines Tages Ihr Modellierungswerkzeug wechseln, um neue Programmiersprachen und Plattformen zu unterstützen - und darauf vertrauen, dass Sie Ihre UML-Diagramme in die neue UML-Software übernehmen können.

  • Die Code-Generierung ist umso besser, je komfortabler das Round Trip Engineering für den Entwickler ist. Unter Round Trip Engineering versteht man das gleichzeitige Arbeiten am Modell und am Quellcode. Round Trip Engineering ist das Eingeständnis, dass kein UML-Werkzeug wissen kann, wie der Quellcode im Sinne des Entwicklers genau aussehen soll. Es gibt häufig verschiedene Möglichkeiten, eine Funktion zu implementieren - für den einen Entwickler ist zum Beispiel der Einsatz standardisierter Klassen oder Funktionen wichtig, für den anderen eine hohe Ausführungsgeschwindigkeit des Codes. Entwickler werden also den Quellcode, den ein UML-Werkzeug erstellt, nicht immer automatisch übernehmen, sondern für ihre Ziele optimieren. Round Trip Engineering bedeutet nun, dass Änderungen im Quellcode auch im Modell sichtbar werden. Egal, ob also im Modell oder im Quellcode gearbeitet wird - die andere Seite wird bei Änderungen automatisch aktualisiert.

Eine Code-Generierung, die ein Modell vollständig berücksichtigt, unabhängig von Programmiersprachen und Plattformen ist und komfortables Round Trip Engineering unterstützt, ist für den Entwickler ideal. Je mehr die Code-Generierung eines UML-Werkzeugs an diesen Idealzustand heranreicht, umso teurer ist die Modellierungssoftware. So bietet zum Beispiel IBM die Modellierungssoftware Telelogic Tau, die im Ruf steht, eine hervorragende Code-Generierung zu unterstützen, ab etwa 10.000 Euro an. Dahingegen nimmt sich die für dieses Buch verwendete Referenzsoftware Poseidon for UML Professional Edition zum Preis von etwa 700 Euro geradezu billig aus. Was die Code-Generierung von Poseidon for UML zu diesem Preis bietet, schauen wir uns im Folgenden an.


5.3 Code-Generierung in Poseidon for UML Professional Edition 3.0

Unterstützung beliebiger Programmiersprachen, aber nur eines Diagrammtyps

Poseidon for UML Professional Edition 3.0 gehört zu den wenigen UML-Werkzeugen, deren Code-Generierungsfunktion tatsächlich unabhängig von Programmiersprachen und Plattformen ist. Mit diesem Modellierungswerkzeug können also beliebige Programmiersprachen und Plattformen unterstützt werden. Es werden standardmäßig unter anderem die Programmiersprachen C++, Java, C# und PHP unterstützt. Da die Code-Generierung in Poseidon for UML auf Konfigurationsdateien und einem Plug-In-Mechanismus basiert, kann sie auf beliebige Programmiersprachen erweitert werden.

Auch wenn die Unterstützung beliebig vieler Programmiersprachen das Entwicklerherz höher schlagen lässt, so wird die Freude ein wenig getrübt, was die Unterstützung der Diagrammtypen der UML angeht: Die Code-Generierung in Poseidon for UML basiert ausschließlich auf Klassendiagrammen. Alle anderen Diagrammtypen werden für die Code-Generierung nicht herangezogen. Wenn Sie also Use-Case- oder Aktivitätsdiagramme erstellen, dann tun Sie dies ausschließlich der Übersicht wegen, nicht aber für die Code-Generierung.

Auch Round Trip Engineering wird nur halbherzig unterstützt. Merkwürdigerweise steht diese Funktion nur dann zur Verfügung, wenn als Programmiersprache für die Code-Generierung Java gewählt wurde. Für alle anderen Programmiersprachen steht kein Round Trip Engineering zur Verfügung.

Wir sehen uns nun an, wie die Code-Generierung in Poseidon for UML funktioniert. Da für die Code-Generierung ausschließlich Klassendiagramme berücksichtigt werden, verwenden wir folgendes Diagramm, das wir aus dem Kapitel 4, Das Klassendiagramm kennen. Es stellt eine Gesamtübersicht aller Klassen dar, die wir für unseren Online-Shop brauchen.

Die Code-Generierung ist in Poseidon for UML als Plug-In-Mechanismus implementiert. Jedes Plug-In unterstützt die Überführung von UML in eine Programmiersprache. Indem mehrere Plug-Ins geladen und aktiviert werden, stehen mehrere Übersetzungsmöglichkeiten und damit mehrere Zielprogrammiersprachen zur Verfügung. Da es möglich ist, eigene Plug-Ins zu entwickeln, kann die Code-Generierung in Poseidon for UML auf beliebige Programmiersprachen ausgeweitet werden.

Im Folgenden sehen Sie das Plug-Ins-Fenster von Poseidon for UML, das sämtliche zur Verfügung stehende Plug-Ins auflistet. Für jedes Plug-In können Sie einstellen, ob es aktiviert sein soll oder nicht. Nicht aktivierte Plug-Ins können für eine Code-Generierung nicht genutzt werden. Das Deaktivieren von Plug-Ins kann nützlich sein, um die Übersicht im UML-Werkzeug zu erhöhen, weil nur mehr die Programmiersprachen für eine Übersetzung angeboten werden, die Sie tatsächlich brauchen.

Je nachdem, welche Plug-Ins installiert und aktiviert sind, können Sie die Zielprogrammiersprachen im Menü Generierung auswählen. Über dieses Menü starten Sie die Code-Generierung.

Wenn Sie eine Zielprogrammiersprache ausgewählt haben, öffnet sich folgendes Fenster.

In diesem Fenster können Sie angeben, welche Klassen aus dem Projekt in die Code-Generierung miteinbezogen werden sollen. Standardmäßig befindet sich vor allen Klassennamen ein Häkchen - es wird also Code für alle Klassen generiert. Wenn Sie diese Einstellung verändern und die geänderte Einstellung für spätere Code-Generierungen speichern möchten, achten Sie darauf, dass die Option Aktuelle Baumwahl merken aktiviert ist.

Beachten Sie außerdem, dass Sie einen sinnvollen Pfad für den Ausgabe-Ordner angegeben haben. In diesen Ordner werden nach einem Klick auf die Schaltfläche Generieren die Quellcode-Dateien erzeugt.

Wenn die Code-Generierung erfolgreich ausgeführt werden konnte, sollten Sie im angegebenen Ausgabe-Ordner die Quellcode-Dateien finden. Der erzeugte Java-Quellcode für die Klasse Bestellung sieht zum Beispiel wie folgt aus.

/** 
 * <p></p> 
 */ 
public class Bestellung { 

/** 
 * <p>Represents ...</p> 
 */ 
    private Anschrift[] Lieferanschrift; 

/** 
 * <p></p> 
 */ 
    public Warenkorb warenkorb; 

/** 
 * <p></p> 
 */ 
    private Anschrift Rechnungsanschrift; 

/** 
 * <p></p> 
 */ 
    public Zahlungsmethode zahlungsmethode; 

/** 
 * <p>Does ...</p> 
 * 
 * 
 * 
 * @param artikelnummer 
 * @param anzahl 
 */ 
    public void Reinlegen(Integer artikelnummer, Integer anzahl) { 
        // your code here 
    } 

/** 
 * <p>Does ...</p> 
 * 
 * 
 * 
 * @param artikelnummer 
 * @param anzahl 
 */ 
    public void Rausnehmen(Integer artikelnummer, Integer anzahl) { 
        // your code here 
    } 
} 

Die Code-Generierung funktioniert zwar, ein Kompilieren des erzeugten Quellcodes würde aber nicht viel Sinn machen. Die Klassen mit ihren Eigenschaften und Methoden liegen zwar nun als Java-Code vor, nur ist keine einzige Methode implementiert. Die Methodenrümpfe sind alle leer.

Hier kommt das Manko von Poseidon for UML am stärksten zum Vorschein: Methoden sind Abläufe und werden durch Verhaltensdiagramme wie zum Beispiel Aktivitätsdiagramme modelliert. Da jedoch für die Code-Generierung nur Klassendiagramme herangezogen werden, kann im erzeugten Quellcode lediglich die Methode definiert werden, ohne dass sie implementiert werden kann. Hier ist nun Handarbeit angesagt: Im generierten Quellcode müssen alle Methoden implementiert werden, um dann den Quellcode kompilieren zu können und die gewünschte Software zu erhalten.

Sie können Methoden jedoch auch innerhalb des UML-Werkzeugs implementieren. Dazu steht ein in Poseidon for UML integrierter Quellcode-Editor zur Verfügung, der Code-Vorschau genannt wird. Mit diesem Quellcode-Editor arbeiten Sie dann innerhalb einer Entwicklungssoftware, was grundsätzlich von Vorteil ist. Da jedoch der Quellcode-Editor von Poseidon for UML bei weitem nicht mit Entwicklungsumgebungen mithalten kann, in denen der Quellcode-Editor im Mittelpunkt steht und mit allerlei hilfreichen Funktionen ausgerüstet ist, ist diese Option nur eingeschränkt zu empfehlen. Eine Code-Generierung und anschließende Bearbeitung des Quellcodes in einem professionellen Quellcode-Editor ist in den meisten Fällen wohl der bessere Weg.

In der Version 3.0 bietet Poseidon for UML erstmals die Möglichkeit, die Modellierungssoftware in die Entwicklungsumgebung Eclipse zu integrieren. Da Eclipse eine ausgewachsene Entwicklungsumgebung ist, bekommen Sie durch die Integration das Beste aus zwei Welten: Eine ausgereifte Modellierungssoftware und einen überzeugenden Quellcode-Editor. Einziger Haken: Eclipse unterstützt ausschließlich Java, wenn auch die Entwicklung von C++-Programmen durch Plug-Ins in Eclipse möglich ist.

Ebenfalls ausschließlich für die Java-Entwicklung steht das Round Trip Engineering in Poseidon for UML zur Verfügung. Unter Round Trip Engineering versteht man das gleichzeitige Arbeiten am Modell und am Quellcode, wobei Änderungen am Modell oder am Quellcode jeweils automatisch auf der anderen Seite sichtbar werden. Die bereits erwähnte Code-Vorschau kann für das Round Trip Engineering nicht verwendet werden, da sie ausschließlich für die Implementierung von Methoden zur Verfügung steht. Sie können also in der Code-Vorschau keine neuen Klassen erstellen oder Klassen neue Eigenschaften oder Methoden hinzufügen.

Dadurch, dass Round Trip Engineering nicht innerhalb von Poseidon for UML möglich ist, ist diese Funktion wie folgt implementiert: Beim Round Trip Engineering liest Poseidon for UML entweder automatisch alle paar Sekunden oder manuell auf Knopfdruck die Quellcode-Dateien neu ein, die überwacht werden sollen. Der Quellcode kann daher in einem anderen Editor wie einer ausgewachsenen Entwicklungsumgebung bearbeitet werden. Da Poseidon for UML die Quellcode-Dateien überwacht, kann das Modellierungswerkzeug Änderungen erkennen und das Modell aktualisieren.

Der Wechsel zwischen Modellierungswerkzeug und Quellcode-Editor ist natürlich unschön. Eine Integration in eine einzige Programmoberfläche ist wünschenswert. Dies ist seit der Version 3.0 von Poseidon for UML tatsächlich möglich. Die bereits erwähnte Integration des Modellierungswerkzeugs in die Entwicklungsumgebung Eclipse umfasst auch das Round Trip Engineering, was die Entwicklung einer Software sehr erleichtert. Als einziger Wermutstropfen bleibt, dass Round Trip Engineering ausschließlich für Java zur Verfügung steht.


5.4 Zusammenfassung

Die Zukunft von Softwareentwicklungsprozessen

Die Code-Generierung ist der heißersehnte Wunsch, auf Knopfdruck aus einem Modell in Form von UML-Diagrammen eine ausführbare Software erstellen zu können. Eine derartige Funktion würde die Softwareentwicklung von heute tiefgreifend umwälzen, denn ab sofort würden Modelle im Mittelpunkt stehen - und damit Modellierer und keine Programmierer mehr. Auch wenn der Weg bis dahin noch sehr weit ist, ist heute in Umrissen erkennbar, in welche Richtung sich Softwareentwicklungsprozesse verändern und weiterentwickeln werden.