Grundlagen der modellgetriebene Softwareentwicklung Teil 5

Werbung
Grundlagen der modellgetriebene
Softwareentwicklung
Teil 5: Beispiele
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Version 8.0
28.11.2016
Übersetzerbau (1)
Prinzipieller Aufbau eines Übersetzers (vereinfacht):
Quellcode
Zielcode
Lexikalische
Analyse
Syntaxanalyse
Token-Folge
Semantikanalyse
Syntaxbaum
Codeerzeugung
Symboltabelle,
Zwischensprache
Die Grammatik der Quellsprache legt fest,
• welche Token es gibt (Schlüsselwörter, Namen, Zahlen, Operatoren, ...)
• wie die Token syntaktisch verwendet werden dürfen
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-1
Übersetzerbau (2)
Einsatz von Softwaregenerierung:
• Scanner-Generator für die lexikalische Analyse (z.B. flex)
erzeugt aus der Grammatik der Quellsprache einen endlichen Automaten,
der die Zeichenfolge des Quellcodes in eine Token-Folge umsetzt.
Token-Definition
(reguläre Ausdrücke)
Scanner-Generator
Scanner
• Parser-Generator für die Syntaxanalyse (z.B. bison, ANTLR)
erzeugt aus der Grammatik der Quellsprache einen Kellerautomaten,
der die syntaktische Korrektheit von Token-Folgen prüft.
Syntax-Definition
(EBNF)
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Parser-Generator
Parser
Grundlagen der modellgetriebene Softwareentwicklung
5-2
Verteilte Systeme (1)
Ein verteiltes System besteht aus mehreren autonomen Knoten,
die mittels Nachrichtenaustausch über ein Netz kooperieren.
Der Nachrichtenaustausch wird durch die Heterogenität der Knoten erschwert:
• unterschiedliche Hardware
• unterschiedliche Betriebssysteme
• unterschiedliche Programmiersprachen
• deshalb neutrales Übertragungsformat für den Datenaustausch erforderlich
Sender wandelt Daten von seinem lokalen in das neutrale Format
Empfänger wandelt Daten vom neutralen in sein lokales Format
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-3
Verteilte Systeme (2)
Beim RPC (Remote Procedure Call) wird der Nachrichtenaustausch zwischen
zwei Knoten als Prozeduraufruf "verkleidet":
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-4
Verteilte Systeme (3)
Einsatz von Softwaregenerierung:
• Stub-Generator für den RPC
erzeugt aus der Schnittstellen-Beschreibung (den Prozedur-Signaturen)
die Stubs in den erforderlichen Programmiersprachen.
Interface-Definition
(IDL)
Stub-Generator
Client-Stub
Server-Stub
• der Client-Stub ist der Stellvertreter für den Server auf Clientseite
verpackt den Prozeduraufruf mit den Aufrufparametern in eine Nachricht ("marshalling")
packt die Ergebnisparameter aus der Antwortnachricht aus ("unmarshalling")
• der Server-Stub (Skeleton) ist der Stellvertreter für den Client auf Server-Seite
"unmarshalling" und "marshalling" in umgekehrter Reihenfolge
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-5
Beispiel CORBA (1)
CORBA (Common Object Request Broker Architecture) ist eine
von der OMG spezifizierte Plattform für verteilte objektorientierte Anwendungen
• Mittels CORBA-IDL (Interface Definition Language)
die per RPC aufrufbaren Methoden spezifizieren:
// Echo.idl - ein einfaches über CORBA benutzbares Interface
interface Echo {
string echoString(in string mesg);
};
• Mittels IDL-Compiler Client- und Server-Stubs generieren
(z.B. für Java mit idlj, dem IDL-Compiler aus dem Java Development Kit):
idlj -fall Echo.idl
generiert Java-Interface Echo.java , Client-Stub _EchoStub.java ,
Server-Stub EchoPOA.java (POA = Portable Object Adapter)
und weitere Hilfsklassen (EchoHelper, EchoHolder, EchoOperations)
Prof. Dr. H. Drachenfels
Hochschule Konstanz
5-6
Grundlagen der modellgetriebene Softwareentwicklung
Beispiel CORBA (2)
• Methoden-Implementierung durch Erweiterung des Server-Stubs (Skeletons):
// MyEchoImpl.java - implementiert das IDL-Interface Echo
public final class MyEchoImpl extends EchoPOA {
public String echoString(String s) {
return s;
}
}
• Methode auf Server-Seite für Fernaufruf verfügbar machen:
...
MyEchoImpl echoImpl = new MyEchoImpl();
POA poa = ... // Portable Object Adapter
org.omg.CORBA.Object echoObj =
poa.servant_to_reference(echoImpl);
Echo echo = EchoHelper.narrow(echoObj);
Server erzeugt Objekt und
meldet Echo-Referenz dem
CORBA Name Service
NamingContextExt nc = ... // CORBA Name Service
nc.rebind(nc.to_name("EchoObject"), echo);
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-7
Beispiel CORBA (3)
• Methoden-Aufruf auf Client-Seite über Interface-Referenz:
...
ORB orb = ORB.init(args, null);
Client erfragt die Echo-Referenz
beim CORBA Name Service
org.omg.CORBA.Object ncObj =
orb.resolve_initial_references("NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(ncObj);
org.omg.CORBA.Object echoObj = nc.resolve_str("EchoObject");
Echo echo = EchoHelper.narrow(echoObj);
String s = echo.echoString("Hallo");
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-8
Model Driven Architecture (1)
Die Model Driven Architecture (MDA) ist ein Leitfaden der OMG mit dem Ziel,
komplexe Systeme mit Hilfe von Modellen besser zu beherrschen.
Ankündigung im Jahr 2001, MDA Guide 1.0.1 im Jahr 2003, Version 2.0 im Jahr 2014
Der Leitfaden ist ziemlich abstrakt und allgemein gehalten, fasst aber dennoch die
zentralen Begriffe der modellgetriebenen Softwareentwicklung ganz gut zusammen.
• Schwerpunkt ist die Plattformunabhängigkeit von Softwaresystemen
• verwendet die OMG-Standards MOF (Meta Object Facility) und UML 2.0:
MOF ist aufgeteilt in EMOF (Essential MOF) und CMOF (Complete MOF)
→ XMI (XML Metadata Interchange = XML-Mapping für EMOF-Modelle)
→ QVT (Query / View / Transformation)
UML 2.0 ist spezialisierbar mittels Profilen (Stereotypen, Tagged Values, Constraints)
→ OCL (Object Constraint Language)
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-9
Model Driven Architecture (2)
Modelle repräsentieren Systeme:
• Domänenmodell (CIM = Computation Independent Model)
Logisches Systemmodell (PIM = Platform Independent Model)
Implementierungsmodell (PSM = Platform Specific Model)
• System = Teile + Beziehungen + Zweck
System = Anwendung + Plattform
Metamodelle definieren Sprachen, in denen Modelle ausgedrückt werden
Transformationen erzeugen aus Modellen andere Modelle,
Modellrepräsentationen, Modellsichten oder sonstige Artefakte:
• uni- oder bidirektional
• model-to-model, model-to-artifact, artifact-to-model
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-10
Model Driven Architecture (3)
Transformation eines PIM in ein PSM:
PIM
Transformation
Specification
Transformation
Transformation
Record
Die " Transformation Specification" definiert
die Abbildung von Modellelementen:
• Metamodelle als Paramater
• Modelle als Argumente für die Parameter
Ein "Transformation Record " ist die
Aufzeichnung einer durchgeführten
Transformation
• zur Konsistenzsicherung gedacht
(PIM / PSM-Änderungen synchronisieren)
PSM
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-11
Eclipse Modeling Project: Überblick
Das Eclipse Modeling Project möchte die modell-basierte Entwicklung mit
Frameworks, Werkzeugen und der Implementierung von Standards unterstützen.
Themengebiete (entnommen www.eclipse.org/modeling/modeling-charter.php):
Bereitstellung eines Framework
für den Umgang mit Modellen
(editieren, validieren, testen, speichern usw.)
• Abstract Syntax Development
• Concrete Syntax Development
Unterstützung für sowohl graphische
als auch textuelle Syntax
• Model Transformation
• Model to Text Generation
OMG-Standards: MOF, UML, MDA, QVT, XMI, ...
sonstige Standards: BPMN, BPDM, XSD
• Industry Standards
• Domain-Specific Modeling
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-12
Eclipse Modeling Project: EMF
Das EMF (Eclipse Modeling Framework) unterstützt die Generierung von
Werkzeugen und Anwendungen aus einem strukturierten Datenmodell.
• enthält als Kern das (Meta-)Metamodell Ecore, mit dem die abstrakte Syntax
von Datenmodellen definiert werden kann
Klassen (EClass) mit Oberklassen, Attributen (EAttribute) und Referenzen (EReference)
soll redundante Definitionen in UML, XML, Java ersetzen
entspricht EMOF von MDA
Metamodelle werden im XMI-Format als .ecore-Datei serialisiert
• Generierung von Java-APIs für Modell-Instanzierung und -Zugriff
• Generierung eines Modelleditors
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-13
Eclipse Modeling Project: Teilprojekte
ausgewählte Teilprojekte nach Technologien gruppiert
(entnommen eclipse.org/modeling):
• Server and Storage
EMFStore, Model Transaction, ...
• User Interface
EMF Client Platform, Extended Editing Framwork, ...
• Graphical Modeling
Sirius, GMF Tooling / Runtime / Notation, Graphiti
• Modeling Tools
OCL, Papyrus (als UML-Editor verwendbar), Sphinx, ...
• Model Transformation
ATL, Epsilon, MMT, ...
• Textual Modeling
Xtext (sehr ausgereift und erfolgreich)
• Additional Modeling Frameworks
Amalgam (mit allen erforderlichen Plug-Ins vorkonfigurierte Eclipse-Distributionen)
EMF Compare / Diff / Merge
Validation Framework
...
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-14
AspectJ: Aspektorientierte Programmierung mit Java
In Software-Systemen gibt es oft Querschnitts-Aspekte ("Crosscutting Concerns"),
die nicht in einer Komponente konzentriert werden können,
sondern in viele Komponenten verwoben werden müssen.
Beispiele:
• Logging - Programmablauf protokollieren
• Profiling - Programmverhalten vermessen
• Sicherheit - Berechtigungen für Zugriffe prüfen
• Beobachtermuster - Beobachter verwalten und benachrichtigen
AspectJ erweitert Java um Sprachmittel zur Modularisierung solcher Aspekte:
• Aspekte (aspects) fassen Code (advices) zusammen,
der an verstreuten Stellen im Programm (join points / pointcuts)
ausgeführt wird
• Aspekte können Klassen um Deklarationen ergänzen
(inter-type declarations)
• Aspekte werden mit dem restlichen Code zu einem Java-Programm verwoben
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-15
AspectJ: Join Points und Pointcuts
Ein Join Point ist ein wohldefinierter Punkt im Programmablauf,
an dem potentiell Aspekt-Code eingefügt werden kann:
• Aufruf einer Methode oder eines Konstruktors
die Join Points sind
• Ausführung eines Methodenrumpfs
durch die Struktur der
• Zugriff auf ein Feld
Sprache Java vorgegeben
• Behandlung einer Ausnahme
Ein Pointcut ist ein benannter Ausschnitt aus der Menge aller Join Points:
pointcut setter(): call(* Beispiel.set*(..))
alle Aufrufe von Methoden der Klasse Beispiel, deren Name mit set beginnt
pointcut setterAndAdder():
call(* Beispiel.set*(..)) ||
call(* Beispiel.add*(..))
alle Aufrufe von Methoden der Klasse Beispiel, deren Name mit set oder add beginnt
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-16
AspectJ: Advices
Ein Advice ist Code, der ausgeführt wird,
wenn ein Join Point aus einem bestimmten Pointcut erreicht wird.
Der Code kann direkt vor Erreichen des Join Points (before),
direkt nach Erreichen des Join Points (after)
oder sowohl als auch (around) ausgeführt werden.
before(): setter() {
System.out.println("calling " + thisJoinPoint);
}
vor Aufruf eines Setters eine Meldung ausgeben
after() returning: setterAndAdder() {
System.out.println("returned from " + thisJoinPoint);
}
nach erfolgreichem Aufruf eines Setters oder Adders eine Meldung ausgeben
(nicht erfolgreiche Aufrufe: throwing statt returning, ohne Angabe beides)
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-17
AspectJ: Inter-Type Declarations
Mit Inter-Type Declarations können bestehende Klassen
um eine Oberklasse, Interfaces, Konstruktoren, Instanzvariablen und -methoden
erweitert werden.
declare parents:
Beispiel implements Cloneable;
public Object Beispiel.clone()
throws CloneNotSupportedException {
return super.clone();
}
Erweiterung der Klasse Beispiel um die Implementierung des Interfaces Cloneable
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-18
AspectJ: Aspects
Ein Aspect fasst Pointcuts, Advices und Inter-Type Declarations
in einer syntaktischen Einheit zusammen.
Definition im Stil einer Klasse:
public aspect SetterTracing {
pointcut setter(): call(* Beispiel.set*(..))
before(): setter() {
System.out.println("calling " + thisJoinPoint);
}
declare parents: Beispiel implements Cloneable;
public Object Beispiel.clone()
throws CloneNotSupportedException {
return super.clone();
}
}
Aspektinstanzen sind standardmäßig Singletons
(alternativ perthis(), pertarget(), percflow(), percflowbelow())
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-19
Language-oriented Programming
Language-oriented Programming ist ein auf Metaprogrammierung beruhender
Programmierstil, bei dem Programmierer zunächst eine oder mehrere DSLs für
ihre Problemstellung entwerfen und die Problemlösung dann mit diesen DSLs
formulieren.
Schritt 1:
auf Metaebene DSLs definieren
(mit den Mitteln der Meta-Metaebene)
Schritt 2:
auf Programmierebene die Problemlösung formulieren
(mit den Mitteln der DSLs aus Schritt 1)
Schritt 3:
Werkzeuge implementieren (Editoren, Parser, ...)
(für die DSLs aus Schritt 1)
Schritt 4:
ausführbares Programm erzeugen
(aus der in Schritt 2 mittels DSLs formulierten Problemlösung
unter Verwendung der in Schritt 3 erstellten Werkzeuge)
Schritte 2 und 3 alternativ in umgekehrter Reihenfolge oder parallel
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-20
Metaprogrammierung
Bei der Metaprogrammierung werden (Meta-)Programme geschrieben,
die (Objekt-)Programme verarbeiten.
mögliche Formen der Verarbeitung sind:
• analysieren
Beispiel: das Java-Reflection-API erlaubt es, Java-Klassen zu analysieren
• transformieren
Beispiel: javac transformiert Java-Quellcode in JVM-Bytecode
• generieren
Beispiel: flex, bison, antlr generieren Scanner- und Parser-Programme
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-21
Generische Programmierung: Idee
Die Idee der generischen Programmierung (Generic Programming) ist, bei der
Programmierung von Algorithmen und Datenstrukturen von konkreten Typen zu
abstrahieren. Die Typen werden erst bei der Benutzung der Algorithmen bzw.
Datenstrukturen ergänzt (parametrische Polymorphie).
• in Java ist die Idee ansatzweise mit Generics umgesetzt:
z.B. verkettete Liste mit Elementtyp E im Paket java.util
public class LinkedList<E> ... { ... }
LinkedList<Integer> listOfIntegers = ...;
LinkedList<String> listOfStrings = ...;
z.B. Sortieralgorithmus für Felder mit Elementtyp T in der Klasse java.util.Arrays
public static <T> void sort(T[] a, Comparator<? super T> c) { ... }
Generics sorgen lediglich für statische Typsicherheit.
Der übersetzte Code arbeitet einheitlich mit dem Elementtyp java.lang.Object.
• in C++ ist die Idee deutlich weitergehend mit Templates umgesetzt
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Grundlagen der modellgetriebene Softwareentwicklung
5-22
Generische Programmierung: C++ Templates
Der C++-Compiler verwendet Templates als Vorlage,
um für jede Template-Instanzierung eigenen Code zu erzeugen:
// templates.cpp
#include <iostream>
template<typename T>
T max(T x, T y)
{
return x > y ? x : y;
}
int main()
{
std::cout << max(1, 2) << '\n';
std::cout << max(3.4, 4.5) << '\n';
}
Prof. Dr. H. Drachenfels
Hochschule Konstanz
Der Compiler erzeugt hier
zwei Implementierungen:
int max(int x, int y)
{
return x > y ? x : y;
}
double max(double x,
double y)
{
return x > y ? x : y;
}
Grundlagen der modellgetriebene Softwareentwicklung
5-23
Herunterladen