Overcoming the
 Impedance Mismatch
Between Source Code
   and Architecture
                              Peter Friese, itemis

                                     @peterfriese
                                      @xtext




  (c) 2009 Peter Friese. Distributed under the EDL V1.0 - http://www.eclipse.org/org/documents/edl-v10.php
                         More info: http://www.peterfriese.de / http://www.itemis.com
Stop drawing useless
       diagrams
and writing boring code
                              Peter Friese, itemis

                                     @peterfriese
                                      @xtext




  (c) 2009 Peter Friese. Distributed under the EDL V1.0 - http://www.eclipse.org/org/documents/edl-v10.php
                         More info: http://www.peterfriese.de / http://www.itemis.com
UML - One Language To Rule Them All




                          http://en.wikipedia.org/wiki/File:UML_Diagrams.jpg
UML doesn’t cut it!
Increasing Gap
od els
         M

         Code




Increasing Gap
(UML) Models = Shelfware
                   http://www.flickr.com/photos/misterdna/49841409/
Solution:
Two-Way Tools
Result: Bloated Diagrams No-one can understand

                                    Person                                  SomeOtherMeaninglessClass




         User           Author         Administrator       Librarian        SomeOtherMeaninglessClass




                                                                                            SomeOtherMeaninglessClass


                                                            Library               Fee




                                                             Book                Page
        SomeOtherMeaninglessClass



                                                             Shelf                 Folder
        SomeOtherMeaninglessClass




        SomeOtherMeaninglessClass      SomeOtherMeaninglessClass       SomeOtherMeaninglessClass
Solution: Semantic Diagrams



             <<EntityBean>>
                   Book
         title: String
         isbn: String
Instead of being a
solution...
... two-way tools
                                                 have proven to be
                                                 a dead-end




http://www.flickr.com/photos/cgommel/561929101/
... two-way tools
                                                 have proven to be
                                                 a dead-end




http://www.flickr.com/photos/cgommel/561929101/
Let’s step back
What are the real problems?
Boring code
Accidental complexity
Wrong level of abstraction
Anatomy of Modern Software




         Software artifact
Anatomy of Modern Software




    manually written code      Frameworks




                   Libraries
Anatomy of Modern Software


                   manually written
                       code

                                      Frameworks

 schematic code (manually written)



                      Libraries
(Rote) coding doesn’t cut it either!
Problems
Problems




Can we solve them with models?
Yes, we can!
Code Generation Helps

 Model
                  manually written
                      code
Generator
                                     Frameworks

    schematic code (generated)




                      Libraries
MDSD

Metamodel




 <<instanceof>>



                              generated     manually written
 Model             Model
                              code              code

                  Generator




                                          Platform
MDSD with UML

     Metamodel




<<instanceof>>



                                generated     manually written
       Model         Model
                                code              code
                    Generator




        UML                                 Platform
UML and MDSD
A Marriage Made in Heaven?
Not.
UML and MDSD
⊕ Existing tools
⊕ Good overview
⊕ Graphical - managers / clients like that
⊖ complex meta model
⊖ teamwork challenging at best
⊖ model evolution problematic
⊖ UML is too generic, it’s not a DSL
⊖ UML profiles don’t help either
⊖ tools not integrated in IDE
⊖ long round trips
⊖ developers don’t like diagrams that much
UML doesn’t cut it!
Looking at the drawbacks...
UML and MDSD
⊖ complex meta model
⊖ teamwork challenging at best
⊖ model evolution problematic
⊖ UML is too generic, it’s not a DSL
⊖ UML profiles don’t help either
⊖ tools not integrated in IDE
⊖ long round trips
⊖ developers don’t like diagrams that much
... these are promises of DSLs!
What are DSLs?
Suppose...
You’d want to core an apple...
... for your kids.
?
Right tool for the job?
Your trusty swiss army knife!
You can use it for other stuff, too.
  E.g., opening a bottle of wine.
Suppose...
You’d want to core a few more apples...
... for an apple cake.
Still the best tool for the job?
Better use this one.
and this one:
BUT

avoid the unitasker!
BUT

avoid the unitasker!
A DSL is...
A specific tool
for a specific job
A specific tool
for a specific job
DSL Samples
select name, salary
 from employees
 where salary > 2000
 order by salary
<project name="MyProject" default="dist" basedir=".">
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist" location="dist"/>

  <target name="init">
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init">
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile">
    <mkdir dir="${dist}/lib"/>
    <jar jarfile="${dist}/lib/MyProject.jar"
         basedir="${build}"/>
  </target>

  <target name="clean">
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>
<project name="MyProject" default="dist" basedir=".">
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist" location="dist"/>

  <target name="init">
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init">
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile">
    <mkdir dir="${dist}/lib"/>
    <jar jarfile="${dist}/lib/MyProject.jar"
         basedir="${build}"/>
  </target>

  <target name="clean">
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>
DSL Advantages
⊕ Focussed
⊕ Precise metamodel, perfect fit
⊕ No misuse / mismodeling (thanks to
  constrained meta model)
⊕ diff / merge possible
⊕ teamwork possible
⊕ developers like text
⊖ need to build your own tools
DSL Disadvantages
⊕ Focussed
⊕ Precise metamodel, perfect fit
⊕ No misuse / mismodeling (thanks to
  constrained meta model)
⊕ diff / merge possible
⊕ teamwork possible
⊕ developers like text
⊖ need to build your own tools
1)Create ANTLR grammar
2)Generate lexer / parser
3)Parser will create parse tree
4)Transform parse tree to semantic model

5)Iterate model
6)Pass model element(s) to template
DSLs are...
Flexible
Adaptable
Complicated
Expensive
- A DSL for Writing DSLs
Underlying Technology
ar
Model




                                    m
                                   m
                               ra
                               G
                             Generator



        Runtime
                  Superclass




                  Subclass              Class




 LL(*) Parser   ECore meta model                Editor
Grammar (similar to EBNF)
 grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals

 generate entity "http://www.xtext.org/example/Entity"

 Model:
   (types+=Type)*;

 Type:
   TypeDef | Entity;

 TypeDef:
   "typedef" name=ID ("mapsto" mappedType=JAVAID)?;

 JAVAID:
   name=ID("." ID)*;

 Entity:
   "entity" name=ID ("extends" superEntity=[Entity])?
   "{"
     (attributes+=Attribute)*
   "}";

 Attribute:
   type=[Type] (many?="*")? name=ID;
grammar org.xtext.example.Entity
    with org.eclipse.xtext.common.Terminals            Meta model inference
generate entity
    "http://www.xtext.org/example/Entity"
                                              entity
Model:
  (types+=Type)*;
                                                                       Model
Type:
  TypeDef | Entity;
                                                                          types
TypeDef:                                                                *
                                                                    Type
  "typedef" name=ID
                                                                 name: EString
  ("mapsto" mappedType=JAVAID)?;
                                                                                                superEntity
JAVAID:
  name=ID("." ID)*;                                      TypeDef                    Entity


Entity:                                       mappedType                                attributes
  "entity" name=ID
                                                                                  Attribute
  ("extends" superEntity=[Entity])?                       JAVAID
                                                                               name: EString
  "{"                                                  name: EString
                                                                               many: EBoolean
    (attributes+=Attribute)*
  "}";                                                                                  type

Attribute:
  type=[Type] (many?="*")? name=ID;
grammar org.xtext.example.Entity
    with org.eclipse.xtext.common.Terminals            Meta model inference
generate entity
    "http://www.xtext.org/example/Entity"
                                              entity                   Rules -> Classes
Model:
  (types+=Type)*;
                                                                       Model
Type:
  TypeDef | Entity;
                                                                          types
TypeDef:                                                                *
                                                                    Type
  "typedef" name=ID
                                                                 name: EString
  ("mapsto" mappedType=JAVAID)?;
                                                                                                superEntity
JAVAID:
  name=ID("." ID)*;                                      TypeDef                    Entity


Entity:                                       mappedType                                attributes
  "entity" name=ID
                                                                                  Attribute
  ("extends" superEntity=[Entity])?                       JAVAID
                                                                               name: EString
  "{"                                                  name: EString
                                                                               many: EBoolean
    (attributes+=Attribute)*
  "}";                                                                                  type

Attribute:
  type=[Type] (many?="*")? name=ID;
grammar org.xtext.example.Entity
    with org.eclipse.xtext.common.Terminals            Meta model inference
generate entity
    "http://www.xtext.org/example/Entity"
                                              entity            Alternatives -> Hierarchy
Model:
  (types+=Type)*;
                                                                       Model
Type:
  TypeDef | Entity;
                                                                          types
TypeDef:                                                                *
                                                                    Type
  "typedef" name=ID
                                                                 name: EString
  ("mapsto" mappedType=JAVAID)?;
                                                                                                superEntity
JAVAID:
  name=ID("." ID)*;                                      TypeDef                    Entity


Entity:                                       mappedType                                attributes
  "entity" name=ID
                                                                                  Attribute
  ("extends" superEntity=[Entity])?                       JAVAID
                                                                               name: EString
  "{"                                                  name: EString
                                                                               many: EBoolean
    (attributes+=Attribute)*
  "}";                                                                                  type

Attribute:
  type=[Type] (many?="*")? name=ID;
grammar org.xtext.example.Entity
    with org.eclipse.xtext.common.Terminals            Meta model inference
generate entity
    "http://www.xtext.org/example/Entity"
                                              entity               Assignment -> Feature
Model:
  (types+=Type)*;
                                                                       Model
Type:
  TypeDef | Entity;
                                                                          types
TypeDef:                                                                *
                                                                    Type
  "typedef" name=ID
                                                                 name: EString
  ("mapsto" mappedType=JAVAID)?;
                                                                                                superEntity
JAVAID:
  name=ID("." ID)*;                                      TypeDef                    Entity


Entity:                                       mappedType                                attributes
  "entity" name=ID
                                                                                  Attribute
  ("extends" superEntity=[Entity])?                       JAVAID
                                                                               name: EString
  "{"                                                  name: EString
                                                                               many: EBoolean
    (attributes+=Attribute)*
  "}";                                                                                  type

Attribute:
  type=[Type] (many?="*")? name=ID;
Demo
Do DSLs cut it?
Yes, they do
Yes, they do
Yes, they do
Yes, they do
Concentrate on
  Essentials
Higher Efficiency
Better Maintainability
No More Boring Code
A New Babylonic
Plethora of Languages?
DSLs will improve
communication in projects
Four Things To Take Home
  Beware of the shelfware trap


  Stop writing boring code


  Choose appropriate abstractions


  Better understand your stakeholders

Overcoming The Impedance Mismatch Between Source Code And Architecture

  • 1.
    Overcoming the ImpedanceMismatch Between Source Code and Architecture Peter Friese, itemis @peterfriese @xtext (c) 2009 Peter Friese. Distributed under the EDL V1.0 - http://www.eclipse.org/org/documents/edl-v10.php More info: http://www.peterfriese.de / http://www.itemis.com
  • 2.
    Stop drawing useless diagrams and writing boring code Peter Friese, itemis @peterfriese @xtext (c) 2009 Peter Friese. Distributed under the EDL V1.0 - http://www.eclipse.org/org/documents/edl-v10.php More info: http://www.peterfriese.de / http://www.itemis.com
  • 3.
    UML - OneLanguage To Rule Them All http://en.wikipedia.org/wiki/File:UML_Diagrams.jpg
  • 4.
  • 6.
  • 7.
    od els M Code Increasing Gap
  • 8.
    (UML) Models =Shelfware http://www.flickr.com/photos/misterdna/49841409/
  • 9.
  • 10.
    Result: Bloated DiagramsNo-one can understand Person SomeOtherMeaninglessClass User Author Administrator Librarian SomeOtherMeaninglessClass SomeOtherMeaninglessClass Library Fee Book Page SomeOtherMeaninglessClass Shelf Folder SomeOtherMeaninglessClass SomeOtherMeaninglessClass SomeOtherMeaninglessClass SomeOtherMeaninglessClass
  • 11.
    Solution: Semantic Diagrams <<EntityBean>> Book title: String isbn: String
  • 12.
    Instead of beinga solution...
  • 13.
    ... two-way tools have proven to be a dead-end http://www.flickr.com/photos/cgommel/561929101/
  • 14.
    ... two-way tools have proven to be a dead-end http://www.flickr.com/photos/cgommel/561929101/
  • 15.
  • 16.
    What are thereal problems?
  • 17.
  • 18.
  • 19.
    Wrong level ofabstraction
  • 20.
    Anatomy of ModernSoftware Software artifact
  • 21.
    Anatomy of ModernSoftware manually written code Frameworks Libraries
  • 22.
    Anatomy of ModernSoftware manually written code Frameworks schematic code (manually written) Libraries
  • 23.
  • 25.
  • 26.
    Problems Can we solvethem with models?
  • 27.
  • 28.
    Code Generation Helps Model manually written code Generator Frameworks schematic code (generated) Libraries
  • 29.
    MDSD Metamodel <<instanceof>> generated manually written Model Model code code Generator Platform
  • 30.
    MDSD with UML Metamodel <<instanceof>> generated manually written Model Model code code Generator UML Platform
  • 31.
  • 32.
    A Marriage Madein Heaven?
  • 33.
  • 34.
    UML and MDSD ⊕Existing tools ⊕ Good overview ⊕ Graphical - managers / clients like that ⊖ complex meta model ⊖ teamwork challenging at best ⊖ model evolution problematic ⊖ UML is too generic, it’s not a DSL ⊖ UML profiles don’t help either ⊖ tools not integrated in IDE ⊖ long round trips ⊖ developers don’t like diagrams that much
  • 35.
  • 37.
    Looking at thedrawbacks...
  • 38.
    UML and MDSD ⊖complex meta model ⊖ teamwork challenging at best ⊖ model evolution problematic ⊖ UML is too generic, it’s not a DSL ⊖ UML profiles don’t help either ⊖ tools not integrated in IDE ⊖ long round trips ⊖ developers don’t like diagrams that much
  • 39.
    ... these arepromises of DSLs!
  • 40.
  • 41.
  • 42.
    You’d want tocore an apple...
  • 43.
  • 44.
  • 45.
    Your trusty swissarmy knife!
  • 46.
    You can useit for other stuff, too. E.g., opening a bottle of wine.
  • 47.
  • 48.
    You’d want tocore a few more apples...
  • 49.
    ... for anapple cake.
  • 50.
    Still the besttool for the job?
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
    A specific tool fora specific job
  • 57.
    A specific tool fora specific job
  • 58.
  • 59.
    select name, salary from employees where salary > 2000 order by salary
  • 60.
    <project name="MyProject" default="dist"basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <mkdir dir="${build}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <mkdir dir="${dist}/lib"/> <jar jarfile="${dist}/lib/MyProject.jar" basedir="${build}"/> </target> <target name="clean"> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>
  • 61.
    <project name="MyProject" default="dist"basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <mkdir dir="${build}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <mkdir dir="${dist}/lib"/> <jar jarfile="${dist}/lib/MyProject.jar" basedir="${build}"/> </target> <target name="clean"> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>
  • 62.
    DSL Advantages ⊕ Focussed ⊕Precise metamodel, perfect fit ⊕ No misuse / mismodeling (thanks to constrained meta model) ⊕ diff / merge possible ⊕ teamwork possible ⊕ developers like text ⊖ need to build your own tools
  • 63.
    DSL Disadvantages ⊕ Focussed ⊕Precise metamodel, perfect fit ⊕ No misuse / mismodeling (thanks to constrained meta model) ⊕ diff / merge possible ⊕ teamwork possible ⊕ developers like text ⊖ need to build your own tools
  • 64.
    1)Create ANTLR grammar 2)Generatelexer / parser 3)Parser will create parse tree 4)Transform parse tree to semantic model 5)Iterate model 6)Pass model element(s) to template
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
    - A DSLfor Writing DSLs
  • 71.
  • 72.
    ar Model m m ra G Generator Runtime Superclass Subclass Class LL(*) Parser ECore meta model Editor
  • 73.
    Grammar (similar toEBNF) grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/example/Entity" Model: (types+=Type)*; Type: TypeDef | Entity; TypeDef: "typedef" name=ID ("mapsto" mappedType=JAVAID)?; JAVAID: name=ID("." ID)*; Entity: "entity" name=ID ("extends" superEntity=[Entity])? "{" (attributes+=Attribute)* "}"; Attribute: type=[Type] (many?="*")? name=ID;
  • 74.
    grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  • 75.
    grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Rules -> Classes Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  • 76.
    grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Alternatives -> Hierarchy Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  • 77.
    grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Assignment -> Feature Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  • 78.
  • 80.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
    Concentrate on Essentials
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
    Four Things ToTake Home Beware of the shelfware trap Stop writing boring code Choose appropriate abstractions Better understand your stakeholders