Folien MDSD2010_1-5

Werbung
Codegenerierung
Modellgetriebene Softwareentwicklung
bei der IBYKUS AG
Theorie – Teil 5:
Codegenerierung
Dr. Steffen Skatulla
IBYKUS AG
03.05.2010
1
Codegenerierung
Inhalt Teil 5: Codegenerierung
•
•
Prinzipien, Einordnung und Abgrenzung
Techniken der Codegenerierung
–
–
–
–
•
Template Engines: JET, XSLT
„Ausprogrammierte“ Generatoren
OAW-Xpand
IBYKUS Techniken
Best Practices
03.05.2010
2
Codegenerierung
Codegenerierung
•
•
•
Model-to-Code-Transformation (M2C)
Erzeugung von (Programm-)Code aus Modellen
Erzeugen Code für eine bestimmte Plattform plattformspezifisch
•
Funktionen für Codegenerierung
–
–
–
–
03.05.2010
Lesen/Abfragen des Input-Modells
Umformen der Informationen
Konkatenieren / Ersetzen von Text
Schreiben in Output-Dateien
3
Codegenerierung
Codegenerierung
•
Für Generierung / Transforamtion nötig
Modell
(abstrakt)
„Ausprogrammierte“
Transformation
(Konkretisierung)
Modell / Code
(weniger abstrakt)
– Widerverwendbarkeit?
– Verständlichkeit?
03.05.2010
4
Codegenerierung
Codegenerierung
•
Für Generierung / Transforamtion nötig
– Template
– Transformations-Engine
•
Separiert vs. integriert
Modell
(abstrakt)
Template
(Konkretisierung)
Trafo-Engine
Modell
(abstrakt)
„Ausprogrammierte“
Transformation
(Konkretisierung)
(allg. wiederverwendbar)
Modell / Code
(weniger abstrakt)
Modell / Code
(weniger abstrakt)
– Widerverwendbarkeit?
– Verständlichkeit?
03.05.2010
5
Codegenerierung
Codegenerierung
•
Für Generierung / Transforamtion nötig
– Template
– Transformations-Engine
•
Separiert vs. integriert vs. generiert
Modell
(abstrakt)
Template
(Konkretisierung)
Trafo-Engine
Modell
(abstrakt)
Modell
(abstrakt)
„Ausprogrammierte“
Transformation
(Konkretisierung)
Generierte
Transformation
Modell / Code
(weniger abstrakt)
Modell / Code
(weniger abstrakt)
Trafo-Modell
(Konkretisierung)
Trafo-Generator
(allg. wiederverwendbar)
Modell / Code
(weniger abstrakt)
– Widerverwendbarkeit?
– Verständlichkeit?
03.05.2010
6
Codegenerierung
Wie „tief“ soll generiert werden?
•
Die Nutzung leistungsfähiger
Plattform-Infrastruktur kann die
Generierung der Anwendung
wesentlich vereinfachen
– Ziel der Generierung ist Code, der
Programmbibliotheken, Frameworks,
Middleware benutzt
– Keine „Durchgenerierung“ bis zum
Bytecode
•
Aber es gibt auch Gründe bei Bedarf
„tiefer“ zu generieren
Modell
Generierung
Generierung auf
Frameworkbasis
Bauteilvorlagen
Code
mit
Code auf
Frameworkbasis
Spezialbausteinen
Framework mit
Universal-Bausteinen
Programmiersprache,
Basisbibliotheken, …
03.05.2010
7
Codegenerierung
Was ist mit Generierung möglich?
•
Performance und geringe Codegröße trotz Flexibilität
– Flexible Frameworks arbeiten oft dynamisch / interpretativ
– Dadurch sind sie tendenziell weniger performant und umfangreicher
– Flexible Generierung
• Statischen Codes Performance
• Nur des benötigten Codes geringe Codegröße
•
Analysierbarkeit
– Statischer generierter Code ist besser analysierbar als dynamische /
interpretative Frameworks
•
Fehlerfrüherkennung
– Bei statische generierten Typen treten Fehler zur Compilezeit auf
und nicht erst zur Laufzeit, wie bei dynamischer Typisierung im Framework
•
Einschränkungen der Programmiersprache
– Z.B. Einführung von objektorientierten Konzepten in die Modellierung auch bei
der Generierung in nicht-objektorientierte Programmiersprachen
03.05.2010
8
Codegenerierung
Was ist mit Generierung möglich?
•
Aspekte
– Querschnittsfunktionalität läßt sich zentral an einer Stelle modellieren und bei
der Generierung in alle relevanten Stellen einweben, auch ohne
Aspektorientierte Programmiersprachen
Aspekt-Modell
Modell
Generator
Java-Methode
Querschnittsfunktionalität
Funktion
Querschnittsfunktionalität
03.05.2010
9
Codegenerierung
Generierung mit Templates
•
Template
– Lückentext
– Angabe, wie Lücken zu füllen sind
•
Template-Engines aus der dynamischen Webprogrammierung
– JSP, PHP, …
<html>
<head><title>First Example</title></head>
<body>
<h3>Hello World-JSP</h3>
Your browser is:
<%= request.getHeader("User-Agent") %><br>
Your IP address is:
<%= request.getRemoteAddr() %>
</body>
</html>
03.05.2010
Konkatenieren von Text und Schreiben in Dateien
Verarbeitung von Informationen
Schreiben in mehrere Zieldateien (keine explizite Steuerung in welche)
Unterstützung beim Lesen/Abfragen/Navigieren von Modellen
10
Codegenerierung
Generierung mit Templates:
Java-basierte Template-Engines## Velocity Hello World
•
Verbreitete Vertreter
– JET, Velocity, Freemarker, …
<html>
<body>
#set( $foo = "Velocity" )
## followed by Hallo
$foo Welt!
</body>
</html>
<%@ jet package="hello" imports="java.util.*" class="XMLDemoTemplate" %>
<% List elementList = (List) argument; %>
<?xml version="1.0" encoding="UTF-8"?>
<demo>
<% for (Iterator i = elementList.iterator(); i.hasNext(); ) { %>
<element><%=i.next().toString()%></element>
<% } %>
</demo>
•
Bewertung
03.05.2010
Konkatenieren von Text und Schreiben in Dateien
Verarbeitung von Informationen
Unterstützung beim Lesen/Abfragen von Modellen
Aber nicht optimiert auf Navigation auf Objekt-Netzen (Pfadausdrücke)
Schreiben in mehrere Zieldateien (keine explizite Steuerung in welche)
11
Codegenerierung
Generierung mit Templates: XSLT
•
Für Modelle mit
XML-Repräsentation
Pfadunterstützung
/class/attribute[@type="String"]
XSLT nicht statisch typisiert
Fehler im Modell erst zur
Laufzeit
Komplexe Transformatioen
werden sehr schnell
schlecht lesbar
03.05.2010
<class name="Person">
<attribute name="name" type="String"/>
<attribute name="age" type="int"/>
</class>
<xsl:template match="/class">
public class <xsl:value-of select="@name"/> {
<xsl:apply-templates/>
}
</xsl:template>
<xsl:template match="attribute">
public <xsl:value-of select="@type"/>
<xsl:value-of select="@name"/>;
</xsl:template>
public class Person {
public String name;
public int age;
}
12
Codegenerierung
Generierung mit Templates:
Kriterien für eine gute Template-Sprache
•
Kriterien für eine gute Template-Sprache
–
–
–
–
03.05.2010
Unterstützung von Modularisierung
Kompakte Syntax
Kontrollstrukturen: Bedingungen, Schleifen, …
Komfortable, statisch getypte, effiziente Abfrage- und Navigationssprache für
Modell
13
Codegenerierung
Generierung mit imperativen Programmiersprachen
•
Java, C++, … bringen mit
– Kontrollstrukturen, statische Typisierung, Modularisierbarkeit
•
Sinnvolle Technik
– Klassen für Zielstrukturen
– Objekte werden beim Ablesen des Modells erstellt, parametrisiert, vernetzt
– Codeerzeugung über verschachtelte toString()-Methodenaufrufe
•
Probleme
– Keine mehrzeiligen Literale
String s =
"Das ist Zeile eins \n"
+ "Das ist Zeile zwei \n";
• Zeilenumbruch systemspezifisch \n, \r, \r\n
• Verteilung auf Zeilen erfordert Verkettung
– Anführungszeichen müssen escaped werden
"name=\"" + name + "\"";
– Konkatenation nicht implizit sondern mit +-Operator
03.05.2010
14
Codegenerierung
Generierung mit imperativen Programmiersprachen
– Aufwändige Interation, insbesondere bei variabel tiefer Rekursion
public void loopChildren(Node node) {
for (Node child : node.getChildren()) {
// do something
loopChildren(child);
}
}
– Metamodell muß als Java-Klassen zur Verfügung stehen
• Entweder dynamische Klassen nicht statisch typisiert, umständlich in Handhabung
• Oder Generierung statischer Klassen aus Metamodell aufwändig
03.05.2010
15
Codegenerierung
Template-Sprache Xpand
•
Aus openArchitectureWare
«IMPORT metamodel»
«EXTENSION my::generator::Extensions»
•
Eigenschaften
«DEFINE javaBean FOR Entity»
«FILE name+".java"»
public class «name» {
«EXPAND property FOREACH attributes»
}
«ENDFILE»
«ENDDEFINE»
– Template-Sprache
(Lückentext)
– OO-artige Modularisierung
– Stringkonkatenation durch
hintereinander schreiben
– Typsystem nicht an
Hostsprache gekoppelt
03.05.2010
«DEFINE property FOR Attribute»
public «type» «name»;
public «type» «getterName()»() {
return «name»;
}
public void «setterName()» («type» «name») {
this.«name» = «name»;
}
«ENDDEFINE»
16
Codegenerierung
Template-Sprache Xpand
•
Metamodell importieren
03.05.2010
«IMPORT metamodel»
17
Codegenerierung
Template-Sprache Xpand
•
2 Templates
– Name
– Optionale Parameterliste
– Für bestimmten Typ aus
Metamodell
(statische Typisierung)
«IMPORT metamodel»
«DEFINE javaBean() FOR Entity»
«ENDDEFINE»
«DEFINE property() FOR Attribute»
«ENDDEFINE»
03.05.2010
18
Codegenerierung
Template-Sprache Xpand
•
2 Templates
– Name
– Optionale Parameterliste
– Für bestimmten Typ aus
Metamodell
(statische Typisierung)
•
•
Festlegen in welche Datei
geschrieben wird
Text im DEFINE-Block wird in
jeweils offene Datei
geschrieben
«IMPORT metamodel»
«DEFINE javaBean FOR Entity»
«FILE name+".java"»
public class
{
}
«ENDFILE»
«ENDDEFINE»
«DEFINE property FOR Attribute»
«ENDDEFINE»
03.05.2010
19
Codegenerierung
Template-Sprache Xpand
•
2 Templates
– Name
– Optionale Parameterliste
– Für bestimmten Typ aus
Metamodell
(statische Typisierung)
•
•
•
Festlegen in welche Datei
geschrieben wird
Text im DEFINE-Block wird in
jeweils offene Datei
geschrieben
Ausdrücke in „Franzosen“
(französische
Anführungszeichen)
werden ersetzt
03.05.2010
«IMPORT metamodel»
«DEFINE javaBean FOR Entity»
«FILE name+".java"»
public class «name» {
}
«ENDFILE»
«ENDDEFINE»
«DEFINE property FOR Attribute»
«ENDDEFINE»
20
Codegenerierung
Template-Sprache Xpand
•
Aufruf weiterer Templates mi
«EXPAND templateName
FOR expression»
– Z.B. mit Loop-Ausdruck
FOREACH für Listen
«IMPORT metamodel»
«DEFINE javaBean FOR Entity»
«FILE name+".java"»
public class «name» {
«EXPAND property FOREACH attributes»
}
«ENDFILE»
«ENDDEFINE»
«DEFINE property FOR Attribute»
«ENDDEFINE»
03.05.2010
21
Codegenerierung
Template-Sprache Xpand
•
Ausdruckssprache
– Sprachübergreifende
Expression-Language
& -Engine
– OCL-artig
– Funktional
– Mengenwertig
– Navigierend
– Closures
• Funktionen höhrerer
Ordnung
• Nehmen als Parameter
andere Funktionen auf
• Z.B. für Loops über Listen
«IMPORT metamodel»
«EXTENSION my::generator::Extensions»
«DEFINE javaBean FOR Entity»
«FILE name+".java"»
public class «name» {
«EXPAND property FOREACH attributes»
}
«ENDFILE»
«ENDDEFINE»
«DEFINE property FOR Attribute»
public «type» «name»;
public «type» «getterName()»() {
return «name»;
}
public void «setterName()» («type» «name») {
this.«name» = «name»;
}
«ENDDEFINE»
name
getterName()
myClass.attributes.select(a|a.type=='String')
myClass.attributes.select(a.name|a.type=='String')
03.05.2010
22
Codegenerierung
Template-Sprache Xpand
•
Statische Typisierung auf
Basis des importierten
Metamodells
Fehler zur Compilezeit
•
•
Möglich durch eigenes, von
Xpand getrenntes Typsystem
der Expression-Engine
Mit Java wäre das nicht
möglich
«IMPORT metamodel»
«EXTENSION my::generator::Extensions»
«DEFINE javaBean FOR Entity»
«FILE name+".java"»
public class «name» {
«EXPAND property FOREACH attributes»
}
«ENDFILE»
«ENDDEFINE»
«DEFINE property FOR Attribute»
public «type» «name»;
public «type» «getterName()»() {
return «name»;
}
public void «setterName()» («type» «name») {
this.«name» = «name»;
}
«ENDDEFINE»
EObject obj = ...
if ("Entity“.equals(Obj.eClass().getName)) {
...
}
03.05.2010
23
Codegenerierung
Template-Sprache Xpand
•
Extensions
– Operationen, die dynamisch
an einen Typ angehängt
werden können
– Z.B. getterName() an den
Typ Attribute aus dem
importierten Metamodell
– Extensions werden in eigener
Datei definiert
my::generator::Extensions
my/generator/Extensions.ext
import metamodel;
«IMPORT metamodel»
«EXTENSION my::generator::Extensions»
«DEFINE javaBean FOR Entity»
«FILE name+".java"»
public class «name» {
«EXPAND property FOREACH attributes»
}
«ENDFILE»
«ENDDEFINE»
«DEFINE property FOR Attribute»
public «type» «name»;
public «type» «getterName()»() {
return «name»;
}
public void «setterName()» («type» «name») {
this.«name» = «name»;
}
«ENDDEFINE»
getterName(Attribute this) :
"get“ + name.toFirstUpper();
setterName(Attribute this) :
"set“ + name.toFirstUpper();
03.05.2010
24
Codegenerierung
IBYKUS-Templates
template:Z2M Test(csType="SDW") {
parameter:para kmx(dataType="str" default="X");
parameter:in
ty(nodeType="AP&TY");
parameter:push pad(nodeType="AP&PAD");
parameter:out sub(nodeType="SDW&subject");
parameter:out att(nodeType="SDW&attribute");
loop T(type="AP&TY" searchPattern="${{.ty}}") {
choice:if C1(call="isNull" p1="${{.ty}}") {
then T() {
text T1(|begin_text|
Das ist ein Text.
Hier kommt etwas rein: ${{.kmx}}_${{T.name}}_${{P.name}}.
|end_text|);
};
else E() {
...
};
};
};
};
03.05.2010
25
Codegenerierung
Best Practices
•
Generierter Code soll gut lesbar sein
– Lesbarkeit für Debugging
• Strukturierung
• Formatierung
• Kommentare
– Referenzen ins Modell und zu Generatoren in Kommentaren (Location Strings)
[2010-05-01 11:38:45]
GENERATED FROM TEMPLATE SomeTemplate
MODEL ELEMENT aPackage::aClass::SomeAttribute
•
Klare Trennung von generiertem
und handgeschriebenem Code
–
–
–
–
03.05.2010
Protected Regions Source Cuts Dreistufige Vererbung
…
Plattformschicht
Handgeschriebene,
abstrakte Basisklasse
Generische Schicht
Generierte Klasse
Anpassungsschicht
Handgeschriebene Klasse
26
Codegenerierung
Zusammenfassung
•
•
Prinzipien, Einordnung und Abgrenzung
Techniken der Codegenerierung
–
–
–
–
Template Engines: JET, XSLT
„Ausprogrammierte“ Generatoren
OAW-Xpand
IBYKUS Techniken
•
Best Practices
•
Als nächstes
– Modellinterpretation
03.05.2010
27
Herunterladen