Übersicht Inhaltsverzeichnis Vorwort 1 Einführung 2 Agile und UML-basierte Methodik 3 Kompakte Übersicht zur UML/P 4 Prinzipien der Codegenerierung 4.1 Konzepte der Codegenerierung 4.2 Techniken der Codegenerierung 4.3 Semantik der Codegenerierung 4.4 Flexible Parametrisierung eines Codegenerators 5 Transformationen für die Codegenerierung 6 Grundlagen des Testens 7 Modellbasierte Tests 8 Testmuster im Einsatz 9 Refactoring als Modelltransformation 10 Refactoring von Modellen 11 Zusammenfassung und Ausblick Literatur |
4.3 Semantik der CodegenerierungEine Codegenerierung ist im Prinzip eine Transformation eines Modells einer Sprache in eine andere Sprache. Auch eine Semantikdefinition ist im Wesentlichen eine Abbildung einer als unbekannt betrachteten Sprache (hier also UML/P) in eine als bekannt und als verstanden angesehene Zielsprache. Ist die Zielsprache darüber hinaus formal und die Abbildung präzise formuliert, so wird auch von einer formalen Semantik gesprochen. In diesem Sinn kann eine durch ein Programm implementierte Abbildung der UML/P in die Programmiersprache Java selbst als eine formale Semantik verstanden werden [HR04]. Dabei gibt es allerdings mehrere Punkte, die bei dieser Argumentation zu beachten sind:
Als Alternative zu diesen sehr impliziten Semantikdefinitionen lassen sich Techniken der formalen Methoden einsetzen, um eine formale Semantik für die Quellsprache, unabhängig von irgend einer Form der Codegenerierung, zu definieren. Typischerweise sind solche Semantikdefinitionen Abbildungen die eine UML-Variante in eine geeignete Zielsprache transformieren. Als Zielsprachen werden dabei mathematisch formale Kalküle verwendet und die Abbildungen in kompakter Form definiert, so dass sie einer Analyse leichter zugänglich werden.14 Wie in [HR00] und [Rum98] argumentiert, kann die Existenz zweier Abbildungen für eine Quellsprache verwendet werden, um das Zutrauen in die Korrektheit beider Abbildungen und damit insbesondere in die Codegenerierung zu erhöhen. Ist die Codegenerierung in der hier vorgeschlagenen Form parametrisiert und haben die benutzten Skripte Einfluss auf Verhalten und Struktur des generierten Codes, so kann dies auf zwei Arten in eine formale Semantikdefinition einbezogen werden. Abbildung 4.9 formalisiert eine Variante zur Semantikdefinition, in der die Semantikabbildung unabhängig vom benutzten Skript ist.
Zur Formalisierung einer Sprache und der Codegenerierung werden folgende Definitionen benötigt:
Ein Codegenerator ist eine unter Umständen partielle Abbildung Gen : UML → J. Eine formale Semantik ist demgegenüber eine Abbildung Sem : UML → ℙ(Z). Damit wird einem einzelnen typischerweise unterspezifizierten und abstrakten Modell aus der Quellsprache eine Menge von möglichen Implementierungen zugewiesen, die mit eben diesem Modell gemeint sind. Dies stellt eine Form der losen Semantik dar. Für einen Vergleich beider Abbildungen Sem und Gen ist eine Semantik für Java-Programme in der Form SemJava: J → Z notwendig. Dann muss für jedes UML-Dokument u ∈ UML, für das Code generiert werden kann, gelten: Das heißt, im Allgemeinen wählt der Codegenerator eine von mehreren möglichen Implementierungen aus, indem er etwa offene Aspekte durch Defaults ausfüllt. Nur wenn Sem(u) ein einziges Element darstellt, war die Spezifikation offensichtlich vollständig und eindeutig. Ein parametrisierter Codegenerator wird um die Parameter, also die Skriptsprache S, erweitert: Genp : UML × S → J. Es muss nun gelten: Das heißt, im Rahmen der Vorgabe durch Sem(u) darf das Skript s eine mögliche Implementierung für u auswählen. Die in Abbildung 4.9 dargestellte Formalisierung nutzt die mengenwertige Semantikabbildung zum Beispiel auf ein Systemmodell [BCGR09b], um damit die Variabilität des parametrisierten Codegenerators darzustellen. Die Formalisierung hängt sehr stark von den dadurch beobachteten Aspekten einer Sprache ab. Wird zum Beispiel nur das extern sichtbare Verhalten formalisiert, so sind in Bezug auf Umsetzung von Attributen, Assoziationen und anderen Strukturelementen Freiheiten gegeben. Tatsächlich ist es für eine so umfangreiche Sprache wie die UML kaum praktikabel, eine vollständige Formalisierung vorzunehmen, obwohl dies in [Öve00] bemerkenswert vollständig, aber nicht sehr elegant gelungen ist. Stattdessen ist es sinnvoll, einzelne, kritische Aspekte genauer zu beleuchten und damit Rückkopplung in den Standardisierungsprozess zu geben. In einer Reihe von Publikationen wurden auch die prinzipiellen Vorteile und Probleme einer Standardisierung diskutiert [BHH+97, FELR98b, FELR98a]. Eine alternative Sichtweise zu der in Abbildung 4.9 dargestellten Form ist die Einbeziehung der Skriptsprache S in die Semantikdefinition. Quellsprache und Skriptsprache stellen dann in gewisser Weise die gemeinsame „Programmiersprache“ dar. Eine Semantikdefinition kann dies in Form einer Funktion Semp : UML × S → Z widerspiegeln, die die Auswahl genau eines Elements der Zielsprache Z vornimmt.
|
|||||||||