Overcoming The Impedance Mismatch Between Source Code And Architecture

Post on 15-Jan-2015

4,243 views 1 download

Tags:

description

In this talk, I show why UML sucks and why developers should move away from writing *boring* code to writing *exciting* code!

transcript

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.phpMore info: http://www.peterfriese.de / http://www.itemis.com

Stop drawing useless diagrams

and writing boring codePeter Friese, itemis

@peterfriese@xtext

(c) 2009 Peter Friese. Distributed under the EDL V1.0 - http://www.eclipse.org/org/documents/edl-v10.phpMore 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

Increasing Gap

Models

Code

(UML) Models = Shelfware

http://www.flickr.com/photos/misterdna/49841409/

Solution: Two-Way Tools

Result: Bloated Diagrams No-one can understand

Librarian

Person

Fee

Administrator

User

Folder

Shelf

Library

Author

Page

Book

SomeOtherMeaninglessClass

SomeOtherMeaninglessClass

SomeOtherMeaninglessClass

SomeOtherMeaninglessClass

SomeOtherMeaninglessClass

SomeOtherMeaninglessClass

SomeOtherMeaninglessClass

SomeOtherMeaninglessClass

Solution: Semantic Diagrams

title: Stringisbn: String

<<EntityBean>>Book

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

Libraries

Frameworksmanually written code

Anatomy of Modern Software

schematic code (manually written)

Libraries

Frameworks

manually written code

(Rote) coding doesn’t cut it either!

Problems

Problems

Can we solve them with models?

Yes, we can!

schematic code (generated)

Libraries

Frameworks

manually written code

Model

Generator

Code Generation Helps

MDSD

Metamodel

Model

<<instanceof>>

Generator

Modelgeneratedcode

Platform

manually written code

MDSD with UML

UML

Metamodel

Model

<<instanceof>>

Generator

Modelgeneratedcode

Platform

manually written code

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...

⊖ 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 and MDSD

... 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:

avoid the unitasker!

BUT

avoid the unitasker!

BUT

A DSL is...

A specific toolfor a specific job

A specific toolfor a specific job

DSL Samples

select name, salaryfrom employees where salary > 2000order 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 grammar2)Generate lexer / parser3)Parser will create parse tree4)Transform parse tree to semantic model

5)Iterate model6)Pass model element(s) to template

DSLs are...

Flexible

Adaptable

Complicated

Expensive

- A DSL for Writing DSLs

Underlying Technology

Superclass

Subclass Class

ECore meta modelLL(*) Parser Editor

Model

Grammar

Generator

Runtime

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

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;

entity

Model

*

name: EStringType

types

TypeDef Entity

name: EStringJAVAID

superEntity

mappedType

name: EStringmany: EBoolean

Attribute

attributes

type

Meta model inference

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;

entity

Model

*

name: EStringType

types

TypeDef Entity

name: EStringJAVAID

superEntity

mappedType

name: EStringmany: EBoolean

Attribute

attributes

type

Meta model inference

Rules -> Classes

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;

entity

Model

*

name: EStringType

types

TypeDef Entity

name: EStringJAVAID

superEntity

mappedType

name: EStringmany: EBoolean

Attribute

attributes

type

Meta model inference

Alternatives -> Hierarchy

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;

entity

Model

*

name: EStringType

types

TypeDef Entity

name: EStringJAVAID

superEntity

mappedType

name: EStringmany: EBoolean

Attribute

attributes

type

Meta model inference

Assignment -> Feature

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