Agiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit
             Domain Specific Languages -
                 Eine DSL für eine
              generische WebApp - API
                                        Dominik Hirt
                                      efinia UG, Leipzig



20. IndustrieTag InformationsTechnologie      IHK Halle-Dessau   20. November 2012
Agiles Modellieren mit
             Domain Specific Languages -
                 Eine DSL‘s für eine
              generische WebApp - API
                                        Dominik Hirt
                                      efinia UG, Leipzig



20. IndustrieTag InformationsTechnologie      IHK Halle-Dessau   20. November 2012
Dominik Hirt
http://www.efinia.de
Personal Finance Management
Agiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific Languages
Agiles Modellieren mit Domain Specific Languages
Das Modellieren mit
Domain Specific Languages
vereinfacht den Entwicklungs-
prozess und erhöht die
Qualität unserer Software.
^[A-Z0-9._%-]+@(?:[A-Z0-9-]+.)+[A-Z]{2,4}$
^[A-Z0-9._%-]+@(?:[A-Z0-9-]+.)+[A-Z]{2,4}$
SELECT COUNT(*)
FROM Account JOIN Customer
WHERE Account.CustID = Customer.ID
WHERE Customer.Name LIKE ‘D%’
SELECT COUNT(*)
FROM Account JOIN Customer
WHERE Account.CustID = Customer.ID
WHERE Customer.Name LIKE ‘D%’
1.e2-e4 e7-e5
2.Lf1-c4 Sb8-c6
3.Dd1-f3 Lf8-c5
4.Df3xf7#
1.e2-e4 e7-e5
2.Lf1-c4 Sb8-c6
3.Dd1-f3 Lf8-c5
4.Df3xf7#
Unified
 Modeling
Language
Das Problem




Browser   Desktop      Mobile   Tablet


                                   API

           Server / Plattform
Die Ursachen




Redundanz     Abstraktion   Wiederverwendung
Mythos Wiederverwendbarkeit



‣   Klassen

‣   Services

‣   Komponenten

‣   Modelle

‣   Prozesse
Model Driven Software Development




Domäne          Modell        MetaModell
Ein [...] Metamodell stellt die Elemente
einer Modellierungssprache und ihre
Beziehungen in einem Modell dar.
                              [Wikipedia]
grammar de.efinia.webapp.WebAPI with org.eclipse.xtext.xbase.Xbase
generate webAPI "http://www.efinia.de/webapp/WebAPI"
WebAPIModel:
	   functions += Function*
;
Function:
    'function' name = ID '{'
         request=Request
         response=Response
    '}'
;
Request:
    'request' '{'
        'url : ' url=URLType
        ('method :' method=HttpRequestMethod)?
        params+=Parameter*
    '}'
;
URLType:
    '/'ID
;
enum HttpRequestMethod:
    GET='GET' | POST='POST'
;
function createAccount {
	    request {
	    	    url : "/konto"
	    	    method : PUT
        param name String
        param kontoNummer String 1..10
        param blz String 8
    }
    response {
        param accountId long 1..8
    }
}

function updateAccount {
	    request {
	    	    url : "/konto/{accountId}"
	    	    method : POST
        param name String
    }
    response {
        param accountId long 1..8
    }
}

function deleteAccount {
	    request {
	    	    url : "/konto"
	    	    method : DELETE
        param id long
    }
    response {
        param success long 1..8
        error deleteAccountError
    }
}

error deleteAccountError "Konto löschen fehlgeschlagen"
function createAccount {
	    request {
	    	    url : "/konto"
	    	    method : PUT                       RESTful Architektur
        param name String
        param kontoNummer String 1..10
        param blz String 8
    }
    response {
        param accountId long 1..8
    }
}

function updateAccount {
	    request {
	    	    url : "/konto/{accountId}"
	    	    method : POST                   RESTful Architektur
        param name String
    }
    response {
        param accountId long 1..8
    }
}

function deleteAccount {
	    request {
	    	    url : "/konto"
	    	    method : DELETE                 RESTful Architektur
        param id long
    }
    response {
        param success long 1..8
        error deleteAccountError
    }
}

error deleteAccountError "Konto löschen fehlgeschlagen"
grammar de.efinia.dsl.MessagesDsl with org.eclipse.xtext.common.Terminals

generate messagesDsl "http://www.efinia.de/dsl/MessagesDsl"


Messages:
    (allMessages += Message)*
;

Message:
    'message' name = JavaIdentifier
    '{'
         (languages += Language)*
    '}'
;

JavaIdentifier :
  ID ('.' ID)*;

Language:
    name = ID ':' value = STRING
;
Vorher                                  Nachher
<?xml version="1.0" encoding="UTF-8"?>    message impressum.pageTitle {
<messages xmlns:xsi="http://www.w3.org/   	   de : "efinia | Impressum"
2001/XMLSchema-instance"                  }
	                                         message impressum.title {
xsi:noNamespaceSchemaLocation="efiniaMe   	   de : "Impressum"
ssages.xsd">                              }
                                          message login.pageTitle {
	   <message key="impressum.pageTitle">   	   de : "efinia | Login"
	   	   <de>efinia | Impressum</de>       }
	   </message>                            message login.title {
      <message key="impressum.title">     	   de : "Willkommen bei efinia"
          <de>Impressum</de>              }
      </message>

	   <message key="login.pageTitle">
	   	   <de>efinia | Login</de>
	   </message>
	   <message key="login.title">
	   	   <de>Willkommen bei efinia</de>
	   </message>
Vorher                                  Nachher
<?xml version="1.0" encoding="UTF-8"?>    message impressum.pageTitle {
<messages xmlns:xsi="http://www.w3.org/   	   de : "efinia | Impressum"
2001/XMLSchema-instance"                  }
	                                         message impressum.title {
xsi:noNamespaceSchemaLocation="efiniaMe   	   de : "Impressum"
ssages.xsd">                              }
                                          message login.pageTitle {
	   <message key="impressum.pageTitle">   	   de : "efinia | Login"
	   	   <de>efinia | Impressum</de>       }
	   </message>                            message login.title {
      <message key="impressum.title">     	   de : "Willkommen bei efinia"
          <de>Impressum</de>              }
      </message>

	   <message key="login.pageTitle">
	   	   <de>efinia | Login</de>
	   </message>
	   <message key="login.title">
	   	   <de>Willkommen bei efinia</de>
	   </message>



                                                60%
grammar de.efinia.categories.Categories with org.eclipse.xtext.common.Terminals

generate categories "http://www.efinia.de/Categories"

CategoryModel:
    elements += AbstractElement*
;

AbstractElement:
    Category | Keyword
;

Category:
    'category' name = STRING ('-->' parent=[Category|STRING])?
;
	
Keyword:
	   'keyword' name = STRING '-->' category=[Category|STRING]
;
// Hauptkategorien
category "Haus/Wohnung"
category "PKW"
category "Ernährung"

// Unterkategorien
category "Telefon" --> "Haus/Wohnung"
category "Miete" --> "Haus/Wohnung"
category "Strom" --> "Haus/Wohnung"
category "Wasser" --> "Haus/Wohnung"

category "Benzin" --> "PKW"
category "Versicherung" --> "PKW"
category "Steuern" --> "PKW"

// Zuweisung von Schlüsselwörtern
keyword "Telekom" --> "Telefon"
keyword "Vodafone" --> "Telefon"
keyword "O2" --> "Telefon"
keyword "ePlus" --> "Telefon"

keyword "Aldi" --> "Ernährung"
keyword "Netto" --> "Ernährung"
keyword "Edeka" --> "Ernährung"
Model Driven Software Development


MetaModell




                                                       lauffähige
  Modell        Generator          Artefakte
                                                       Software
                                          java
                                             sql
                                               html
                Templates /                       js
           Transformationsregeln
Redundanz
Single Source
MetaModell          Modell




             Test
<Demo>

powered by
‣   Routine Implementierungen

‣   Boilerplate Code

‣   Java Bean Hölle
EFinTLModel:
     useCases+=UseCase*
     dialogs+=Dialog*




                                                   Top Secr
     messages+=Message*
     segments+=Segment*
     datenElementGruppen+=DEG*;
UseCase:




                                                                                       et
     'geschaeftsvorfall' name = ID '{'
          dialogs+=[Dialog]*
     '}';
Dialog:
     'dialog' name = ID '{'
          messages+=[Message]*
     '}';
Message:
     'nachricht' name = ID '{'
          'type' ':' type=NachrichtenType
          'sender' ':' sender=SenderType
          'segments' '{'
              segments += [Segment]
          '}'
     '}';
Segment:
     'segment' kennung=ID name=ID '{'
          datenElemente += (DE | DEGRef)*
          //datenGruppenElemente += (DEGRef)*
     '}';
DE:
     'DE' name=ID ':' format=Format length=Length status=Quantity anzahl=INT restriktion=Constraint)?;
DEGRef:
     'DEG' reference=[DEG] ':' status=Quantity anzahl=INT;
DEG:
     'DEG' name = ID '{'
          gruppenDatenElemente+=(DE)*
     '}';
enum Format:
     an="an" | num="num" | dig="dig" | id="id";
MINMAX_LENGTH:
     min=INT '..' max=INT;
MAX_LENGTH:
     ('..')? max=INT;
EXACT_LENGTH:
     len=INT;
enum Quantity:
     M='Muss' | K='Kann';
QualifiedName:
  ID ('.' ID)*;
enum HBCIVersion :
  v201='201' | v210='210' | v220='220' | v300='300';
enum NachrichtenType :
  K='Kundennachricht' | B='Banknachricht';
enum SenderType :
  K='Kunde' | B='Bank';
blog.todo42.net
d.hirt@efinia.de

Weitere ähnliche Inhalte

PDF
Dojo Und Notes
PPT
Web 2.0 Mit Der Yahoo User Interface Library
PPT
PHP im High End
PDF
Database Change Management
ODP
Präsentation webservices
PDF
Jakob Freund @ BPMN 2010
PPT
XML-Socket-Server zur Kommunikation mit Flash
PDF
JavaServer Faces - Ein schneller Schnelleinstieg
Dojo Und Notes
Web 2.0 Mit Der Yahoo User Interface Library
PHP im High End
Database Change Management
Präsentation webservices
Jakob Freund @ BPMN 2010
XML-Socket-Server zur Kommunikation mit Flash
JavaServer Faces - Ein schneller Schnelleinstieg

Ähnlich wie Agiles Modellieren mit Domain Specific Languages (20)

PPTX
Prototype 1.7
PDF
Einstieg in Xpath für SEO (Campixx2021)
PPTX
Microservices mit Rust
PDF
Welches Webframework passt zu mir? (WJAX)
PDF
Mvc public
PDF
.NET Summit 2016 in München: ASP.NET Core 1
PDF
Javascript auf Client und Server mit node.js - webtech 2010
PDF
Legacy WebApps mit AngularJS pimpen
PDF
Domain Driven Design in Rails
PPT
Übersicht Skriptsprachen
PPTX
Codesmells
PDF
Python builds mit ant
PDF
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
ODP
PDF
IPC 2015 Zend Framework 3 Reloaded
KEY
jQueryMobile mit Extbase/Fluid
PPTX
Angular von 0 auf 100
PDF
Überblick zu Angular2 auf DevCon der Fox-Pro-Usergroup in Frankfurt, Nov 2015
PPTX
Vorlesung SOA - DIS AG.pptx
PPT
AndroMDA - Einführung in eine Open Source Model Driven Architecture Lösung
Prototype 1.7
Einstieg in Xpath für SEO (Campixx2021)
Microservices mit Rust
Welches Webframework passt zu mir? (WJAX)
Mvc public
.NET Summit 2016 in München: ASP.NET Core 1
Javascript auf Client und Server mit node.js - webtech 2010
Legacy WebApps mit AngularJS pimpen
Domain Driven Design in Rails
Übersicht Skriptsprachen
Codesmells
Python builds mit ant
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
IPC 2015 Zend Framework 3 Reloaded
jQueryMobile mit Extbase/Fluid
Angular von 0 auf 100
Überblick zu Angular2 auf DevCon der Fox-Pro-Usergroup in Frankfurt, Nov 2015
Vorlesung SOA - DIS AG.pptx
AndroMDA - Einführung in eine Open Source Model Driven Architecture Lösung
Anzeige

Agiles Modellieren mit Domain Specific Languages

  • 2. Agiles Modellieren mit Domain Specific Languages - Eine DSL für eine generische WebApp - API Dominik Hirt efinia UG, Leipzig 20. IndustrieTag InformationsTechnologie IHK Halle-Dessau 20. November 2012
  • 3. Agiles Modellieren mit Domain Specific Languages - Eine DSL‘s für eine generische WebApp - API Dominik Hirt efinia UG, Leipzig 20. IndustrieTag InformationsTechnologie IHK Halle-Dessau 20. November 2012
  • 12. Das Modellieren mit Domain Specific Languages vereinfacht den Entwicklungs- prozess und erhöht die Qualität unserer Software.
  • 15. SELECT COUNT(*) FROM Account JOIN Customer WHERE Account.CustID = Customer.ID WHERE Customer.Name LIKE ‘D%’
  • 16. SELECT COUNT(*) FROM Account JOIN Customer WHERE Account.CustID = Customer.ID WHERE Customer.Name LIKE ‘D%’
  • 20. Das Problem Browser Desktop Mobile Tablet API Server / Plattform
  • 21. Die Ursachen Redundanz Abstraktion Wiederverwendung
  • 22. Mythos Wiederverwendbarkeit ‣ Klassen ‣ Services ‣ Komponenten ‣ Modelle ‣ Prozesse
  • 23. Model Driven Software Development Domäne Modell MetaModell
  • 24. Ein [...] Metamodell stellt die Elemente einer Modellierungssprache und ihre Beziehungen in einem Modell dar. [Wikipedia]
  • 25. grammar de.efinia.webapp.WebAPI with org.eclipse.xtext.xbase.Xbase generate webAPI "http://www.efinia.de/webapp/WebAPI" WebAPIModel: functions += Function* ; Function: 'function' name = ID '{' request=Request response=Response '}' ; Request: 'request' '{' 'url : ' url=URLType ('method :' method=HttpRequestMethod)? params+=Parameter* '}' ; URLType: '/'ID ; enum HttpRequestMethod: GET='GET' | POST='POST' ;
  • 26. function createAccount { request { url : "/konto" method : PUT param name String param kontoNummer String 1..10 param blz String 8 } response { param accountId long 1..8 } } function updateAccount { request { url : "/konto/{accountId}" method : POST param name String } response { param accountId long 1..8 } } function deleteAccount { request { url : "/konto" method : DELETE param id long } response { param success long 1..8 error deleteAccountError } } error deleteAccountError "Konto löschen fehlgeschlagen"
  • 27. function createAccount { request { url : "/konto" method : PUT RESTful Architektur param name String param kontoNummer String 1..10 param blz String 8 } response { param accountId long 1..8 } } function updateAccount { request { url : "/konto/{accountId}" method : POST RESTful Architektur param name String } response { param accountId long 1..8 } } function deleteAccount { request { url : "/konto" method : DELETE RESTful Architektur param id long } response { param success long 1..8 error deleteAccountError } } error deleteAccountError "Konto löschen fehlgeschlagen"
  • 28. grammar de.efinia.dsl.MessagesDsl with org.eclipse.xtext.common.Terminals generate messagesDsl "http://www.efinia.de/dsl/MessagesDsl" Messages: (allMessages += Message)* ; Message: 'message' name = JavaIdentifier '{' (languages += Language)* '}' ; JavaIdentifier : ID ('.' ID)*; Language: name = ID ':' value = STRING ;
  • 29. Vorher Nachher <?xml version="1.0" encoding="UTF-8"?> message impressum.pageTitle { <messages xmlns:xsi="http://www.w3.org/ de : "efinia | Impressum" 2001/XMLSchema-instance" } message impressum.title { xsi:noNamespaceSchemaLocation="efiniaMe de : "Impressum" ssages.xsd"> } message login.pageTitle { <message key="impressum.pageTitle"> de : "efinia | Login" <de>efinia | Impressum</de> } </message> message login.title { <message key="impressum.title"> de : "Willkommen bei efinia" <de>Impressum</de> } </message> <message key="login.pageTitle"> <de>efinia | Login</de> </message> <message key="login.title"> <de>Willkommen bei efinia</de> </message>
  • 30. Vorher Nachher <?xml version="1.0" encoding="UTF-8"?> message impressum.pageTitle { <messages xmlns:xsi="http://www.w3.org/ de : "efinia | Impressum" 2001/XMLSchema-instance" } message impressum.title { xsi:noNamespaceSchemaLocation="efiniaMe de : "Impressum" ssages.xsd"> } message login.pageTitle { <message key="impressum.pageTitle"> de : "efinia | Login" <de>efinia | Impressum</de> } </message> message login.title { <message key="impressum.title"> de : "Willkommen bei efinia" <de>Impressum</de> } </message> <message key="login.pageTitle"> <de>efinia | Login</de> </message> <message key="login.title"> <de>Willkommen bei efinia</de> </message> 60%
  • 31. grammar de.efinia.categories.Categories with org.eclipse.xtext.common.Terminals generate categories "http://www.efinia.de/Categories" CategoryModel: elements += AbstractElement* ; AbstractElement: Category | Keyword ; Category: 'category' name = STRING ('-->' parent=[Category|STRING])? ; Keyword: 'keyword' name = STRING '-->' category=[Category|STRING] ;
  • 32. // Hauptkategorien category "Haus/Wohnung" category "PKW" category "Ernährung" // Unterkategorien category "Telefon" --> "Haus/Wohnung" category "Miete" --> "Haus/Wohnung" category "Strom" --> "Haus/Wohnung" category "Wasser" --> "Haus/Wohnung" category "Benzin" --> "PKW" category "Versicherung" --> "PKW" category "Steuern" --> "PKW" // Zuweisung von Schlüsselwörtern keyword "Telekom" --> "Telefon" keyword "Vodafone" --> "Telefon" keyword "O2" --> "Telefon" keyword "ePlus" --> "Telefon" keyword "Aldi" --> "Ernährung" keyword "Netto" --> "Ernährung" keyword "Edeka" --> "Ernährung"
  • 33. Model Driven Software Development MetaModell lauffähige Modell Generator Artefakte Software java sql html Templates / js Transformationsregeln
  • 35. MetaModell Modell Test
  • 37. Routine Implementierungen ‣ Boilerplate Code ‣ Java Bean Hölle
  • 38. EFinTLModel: useCases+=UseCase* dialogs+=Dialog* Top Secr messages+=Message* segments+=Segment* datenElementGruppen+=DEG*; UseCase: et 'geschaeftsvorfall' name = ID '{' dialogs+=[Dialog]* '}'; Dialog: 'dialog' name = ID '{' messages+=[Message]* '}'; Message: 'nachricht' name = ID '{' 'type' ':' type=NachrichtenType 'sender' ':' sender=SenderType 'segments' '{' segments += [Segment] '}' '}'; Segment: 'segment' kennung=ID name=ID '{' datenElemente += (DE | DEGRef)* //datenGruppenElemente += (DEGRef)* '}'; DE: 'DE' name=ID ':' format=Format length=Length status=Quantity anzahl=INT restriktion=Constraint)?; DEGRef: 'DEG' reference=[DEG] ':' status=Quantity anzahl=INT; DEG: 'DEG' name = ID '{' gruppenDatenElemente+=(DE)* '}'; enum Format: an="an" | num="num" | dig="dig" | id="id"; MINMAX_LENGTH: min=INT '..' max=INT; MAX_LENGTH: ('..')? max=INT; EXACT_LENGTH: len=INT; enum Quantity: M='Muss' | K='Kann'; QualifiedName: ID ('.' ID)*; enum HBCIVersion : v201='201' | v210='210' | v220='220' | v300='300'; enum NachrichtenType : K='Kundennachricht' | B='Banknachricht'; enum SenderType : K='Kunde' | B='Bank';

Hinweis der Redaktion

  • #2: - Vor dem Start: alle Programme schliessen ausser keynote &amp; 2x Eclipse\n\n
  • #3: \n
  • #4: \n
  • #5: \n
  • #6: \n
  • #7: \n
  • #8: \n
  • #9: wir haben unser B&amp;#xFC;ro in Leipzig\n
  • #10: das ist zwar in Sachsen\n
  • #11: aber zu Sachsen-Anhalt\n
  • #12: und insbesondere zu Halle und zur Martin-Luther-Universit&amp;#xE4;t habe ich ein enges Verh&amp;#xE4;ltniss, da ich hier von 1992-1999 studiert habe.\n
  • #13: Bevor ich fortfahre ... wer hat schon mit Domain Spec. Lang. gearbeitet ?\n
  • #14: \n
  • #15: \n
  • #16: - die F&amp;#xE4;higkeit f&amp;#xFC;r interne DSL&amp;#x2018;s als Erfolgsgrund f&amp;#xFC;r Frameworks wie RoR, Grails\n- wor&amp;#xFC;ber ich heute aber nicht sprechen m&amp;#xF6;chte ist...\n
  • #17: - agil klappt nicht mit UML ... das ist meine pers&amp;#xF6;nliche meinung\n jahrelang versucht, mit einer UML Spec. irgendwas anzufangen, weiterzuverarbeiten ... ohne Erfolg\n
  • #18: - Schnittstellenbeschreibung wichtig f&amp;#xFC;r: \nTechnik\nOrganisation\nzwischenmenschlich\n
  • #19: \n
  • #20: \n
  • #21: - MetaModell beschreibt Modell mit abstrakter Syntax\n- Modell beschreibt die Dom&amp;#xE4;ne mit konkreter Syntax\n- abstrakte Syntax wichtig f&amp;#xFC;r Verarbeitung der Modelle (konkrete Syntax) hingegen nicht\n\n
  • #22: - als Grundlage f&amp;#xFC;r DSL&amp;#x2018;s dienen ,sprachbasierte Metamodelle&amp;#x2018;\n
  • #23: - ggf. in Eclipse zeigen\n
  • #24: \n
  • #25: \n
  • #26: \n
  • #27: \n
  • #28: \n
  • #29: \n
  • #30: \n
  • #31: XML Header sind nicht etwa &amp;#xFC;berfl&amp;#xFC;ssig, diese werden f&amp;#xFC;r/von den Editoren ben&amp;#xF6;tigt\n
  • #32: \n
  • #33: \n
  • #34: \n
  • #35: \n
  • #36: - roundtrip live demo\n
  • #37: - roundtrip live demo\n- CMD-H und danach das Dock-Icon anklicken\n\n
  • #38: \n
  • #39: - ca. 1000 Seiten Spec\n
  • #40: \n
  • #41: \n