Extension and Evolution
Upcoming SlideShare
Loading in...5
×
 

Extension and Evolution

on

  • 907 views

Model-driven software development lecture about techniques for customizing code generated from models.

Model-driven software development lecture about techniques for customizing code generated from models.

Statistics

Views

Total Views
907
Views on SlideShare
905
Embed Views
2

Actions

Likes
1
Downloads
15
Comments
0

1 Embed 2

http://www.slideshare.net 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Extension and Evolution Extension and Evolution Presentation Transcript

  • Extension and Evolution IN4308 Model-Driven Software Development Lecture 12 Eelco Visser Software Engineering Research Group Delft University of Technology Netherlands May 25, 2010
  • Conventional Software Development 'model' 'model' GPL GPL 'machine' 'machine' code code compile compile 'design' 'design' program program code code
  • Conventional Software Maintenance understand understand 'model' 'model' GPL GPL 'machine' 'machine' compile compile 'design' 'design' program program code code modify modify abstractions encoded in program maintenance at low level of abstraction
  • Model-Driven Software Development DSL DSL GPL GPL 'machine' 'machine' program program generate generate compile compile program program code code (model) (model) raise the level of abstraction to a technical or application domain automatically generate implementation code from model
  • Model-Driven Software Evolution modify modify maintenance on models instead of implementation implementation regenerated after modification of models
  • What makes a good DSL?
  • Expressivity expressive dsl requires (much) less code than gpl implementation fewer lines of code = less implementation effort
  • Coverage dsl covers a subset of programs in the target language generator is not surjective
  • Completeness incomplete code generation produces programs with holes to be filled in by developer
  • Portability C# C# dsl-to-csharp dsl-to-csharp dsl-to-java dsl-to-java Java Java abstract over the target domain generate code for multiple platforms from same model
  • Code Quality does generator produce robust and correct code? are errors detected early in the translation pipeline? model verification is preferable over debugging target code
  • DSL Engineering Dimensions ● expressivity ● coverage ● completeness ● portability ● code quality ● evolution
  • Coverage dsl covers a subset of programs in the target language generator is not surjective not all target programs are reachable
  • Coverage of 'Interesting' Programs targeting representatives of equivalence classes can we reach all equivalence classes?
  • Program Equivalence Many programs are the same if we abstract over 'implementation details'. when are two programs the same?
  • Program Equivalence Two programs are the same if they have the same - behaviour - userinterface - effects on the database - performance What is the meaning of 'same'? Abstract over non-important differences Implementation details (e.g. order of statements does not always matter) Look and feel
  • Reasons for Lack of Coverage Completeness only part of the domain is covered Example: domain model vs business logic 80/20 rule : generate 80%, write 20% Tuning the generated code is not exactly what is desired
  • Customization of Generated Code modify not all customizations can be realized in models generated code may need to be adapted
  • Scaffolding (aka Fill in the Blanks) incomplete code generation produces programs with holes to be filled in by developer
  • Scaffolding (aka Fill in the Blanks) Publication Publication title :: String title String authors →→ List<Author> authors List<Author> journal →→ Journal journal Journal public class Publication {{ public class Publication Private String _title; Private String _title; Public String getTitle() {{ Public String getTitle() citation() :: String Return _title; Return _title; citation() String }} Public void setTitle(x :: String) {{ Public void setTitle(x String) _title := x; _title := x; }} …… getters, setters for authors, getters, setters for authors, journal …… journal Public String citation() {{ Public String citation() // fill in code // fill in code }} 'boilerplate code' is generated 'business methods' should be }} filled in by developer
  • Scaffolding Breaks Evolution modify modify modify modify ?? ? ? if model and code are modified, how do we merge the results?
  • Protected Regions modify modify modify copy modify copy modify copy modify copy generator preserves 'protected regions' does not support unanticipated tuning breaks generator encapsulation by exposing implementation
  • Protected Regions public void openUserScreenShowPersons() { ShowPersonsScreenComposite showPersonsScreen = new ShowPersonsScreenComposite(mainController.getShowPerso .getScreenPar this); /*PROTECTED REGION ID(ShowPersons_game_behavior_usecases_perso showPersonsScreen.personList.add("Marcy"); showPersonsScreen.personList.add("Freddy"); showPersonsScreen.personList.add("Mary-Anne"); /*PROTECTED REGION END*/ mainController.getShowPersonsScreenContainer() .showScreen(showPersonsScreen); // next step called by gui to transition...() method } public void systemCallEnd() { /*PROTECTED REGION ID(systemCall_game_behavior_usecases_perso // TODO: perform activity mainController.getShowPersonsScreenContainer().getShell().clo /*PROTECTED REGION END*/ } Source: http://public.tfh-berlin.de/~petrasch/uploads/media/TU_MDAPetrasch_110907.pdf
  • Roundtrip Engineering modify modify extract model from modified code can changes to code be reflected in model? implies lack of abstraction
  • Roundtrip Engineering modify modify modify modify preserve? preserve? Make changes to model and code can changes to code be reflected in model? implies model/code bijection
  • Tuning Generated Code "entity" Id ":" Id "{" Property* Function* "}" -> Entity {cons("Entity")} Entity -- KW["entity"] _1 KW[":"] _2 KW["{"] _3 _4 KW["}"] Entity -- V[V is=2[H[KW["entity"] _1 KW[":"] _2 KW["{"]] _3 _4] KW["}"]] default pretty-print rules can be generated; tuning needed to get it right general: skeleton for user interface from data model need tuning
  • Customization 'From the Outside' customization should never require direct modification of generated code customization code must modify/interact with generated code what is the interface? avoid exposing generation scheme
  • Customization with Partial Classes inputs partial class extends generated class without modifying generated files
  • Customization with Partial Classes public partial class Publication { { public partial class Publication entity Publication { { ////generated code; don't change generated code; don't change entity Publication Author → Author private Author _author; private Author _author; Author → Author … public Author getAuthor () { { public Author getAuthor () … }} return _author; return _author; }} }} public partial class Publication { { public partial class Publication public String citation() { {... public String citation() ... if(this.getAuthor() != null) { { if(this.getAuthor() != null) cc:= cc++getAuthor().getName() := getAuthor().getName() }} ... ... }} }}
  • Evolution with Partial Classes modify modify ?? ?? examples: pp tables, styling
  • Customization with Inheritance class GenPublication { { class GenPublication entity Publication { { ////generated code; don't change generated code; don't change entity Publication Author → Author private Author _author; private Author _author; Author → Author … public Author getAuthor () { { public Author getAuthor () … }} return _author; return _author; }} }} class Publication extends GenPublication { { class Publication extends GenPublication public String citation() { {... public String citation() ... if(this.getAuthor() != null) { { if(this.getAuthor() != null) gen default cc:= cc++getAuthor().getName() := getAuthor().getName() }} ... ... }} }}
  • Generate Subsystem generated code is called from regular code
  • Calling Stratego from C #include <strinclude.h> module foobar module foobar ATerm foo_0_0(StrSL sl, Aterm t) { strategies strategies t = innermost_1_0(...); return t; foo ==innermost(Foo <+ Bar) foo innermost(Foo <+ Bar) } #include “foobar.h” void main() { ATerm t = parse(file); t = foo_0_0(NUL, t); ... } calling convention should be fixed, implementation is hidden
  • Model/Code Interaction customization code should be considered as part of the generator input should interact with (interface of) models, not with generated code
  • Built-in Types aa::::AA f(x.a) f(x.a) class Aimpl { { class Aimpl f() {…} f() {…} }} Aimpl a; Aimpl a; x.a.f() x.a.f() make external code available through type abstraction to model built-in types capture domain-specific functionality
  • Built-in Types: Patch entity PageDiff { page -> Page next -> PageDiff title :: String patch :: Patch created :: Date extend entity Page { previous -> PageDiff function makeChange(.., newText : WikiText,...) date :: Date : Page { author -> User PageDiff { version :: Int ... } patch := newText.makePatch(this.content) ... } } } extend entity PageDiff { function computeContent() : WikiText { if (next = null) { return patch.applyPatch(page.content); } else { return patch.applyPatch(next.content); } }
  • Foreign Function Interface def f f def prim(f) prim(f) call f f call declare functions/types available in 'native' libraries
  • Foreign Function Interface epoch2local-time == epoch2local-time ?EpochTime(t) ?EpochTime(t) ;; prim("SSL_epoch2localtime", t) prim("SSL_epoch2localtime", t) ;; prim-tuple-to-ComponentTime prim-tuple-to-ComponentTime Primitives in Stratego allow calling (wrapped) native functions.
  • Multi Models
  • Multiple Models / Multiple DSLs split model into several models combine DSLs to increase coverage
  • Multiple Models / Multiple DSLs LEX LEX YACC YACC CC CC LEX: lexical analysis with regular grammars YACC: context-free analysis with context-free grammars
  • Multiple Models / Multiple DSLs DM DM UI UI AC AC JPA JPA Servlets Servlets Checks Checks DM: data model UI: user interface AC: access control
  • Model/Model Interaction consider models as components / modules what is interface of a model? what is the scope of model elements model encapsulation; separate compilation
  • LEX & YACC "PRINT" {{ return PRINT; }} "PRINT" return PRINT; [0-9]+ [0-9]+ {{ yylval == atoi(yytext); return NUMBER; }} yylval atoi(yytext); return NUMBER; [a-z] [a-z] {{ yylval == yytext[0] -- 'a'; return NAME; }} yylval yytext[0] 'a'; return NAME; {{ ;; }} n n {{ nextline(); }} nextline(); t t {{ ;; }} "//".*n {{ nextline(); }} "//".*n nextline(); .. {{ yyerror("illegal token"); }} yyerror("illegal token"); statement: statement: designator ASSIGN expression designator ASSIGN expression || PRINT expression PRINT expression || IF expression THEN stmtseq ELSE stmtseq FI IF expression THEN stmtseq ELSE stmtseq FI || IF expression THEN stmtseq FI IF expression THEN stmtseq FI || WHILE expression DO stmtseq OD WHILE expression DO stmtseq OD ;;
  • Language Integration and Separation of Concerns lexical syntax lexical syntax [a-zA-Z][a-zA-Z0-9_]* -> Id [a-zA-Z][a-zA-Z0-9_]* -> Id [a-zA-Z0-9-_]+ [a-zA-Z0-9-_]+ -> FileName -> FileName {FileName "/"}+ {FileName "/"}+ -> ModuleName -> ModuleName ~[nr]* ~[nr]* -> SectionName -> SectionName context-free syntax context-free syntax "{" Statement* "}" "{" Statement* "}" -> Block {cons("Block")} -> Block {cons("Block")} Block Block -> Statement -> Statement "var" Id ":" Sort ";" -> Statement {cons("VarDecl")} "var" Id ":" Sort ";" -> Statement {cons("VarDecl")} Exp ";" Exp ";" -> Statement {cons("Stat")} -> Statement {cons("Stat")} "return" Exp ";" "return" Exp ";" -> Statement {cons("Return")} -> Statement {cons("Return")} context-free syntax context-free syntax "module" ModuleName Section* -> Module {cons("Module")} "module" ModuleName Section* -> Module {cons("Module")} "imports" ModuleName "imports" ModuleName -> Definition {cons("Imports")} -> Definition {cons("Imports")} SDF integrates lexical and contex-free syntax
  • Language Integration and Separation of Concerns WebDSL provides define page topic (topic :: Topic) {{ define page topic (topic Topic) separate languages for …… navigate(editTopic(topic)){…} …… navigate(editTopic(topic)){…} different concerns. }} Language integration define page editTopic(topic :: Topic) {{ enables verified cross- define page editTopic(topic Topic) language references. …… }} userinterface predicate mayViewWeb(w :: Web) {{ predicate mayViewWeb(w Web) ((w.acl.view.length == 0) ((w.acl.view.length 0) || memberOf(w.acl.view)) || memberOf(w.acl.view)) }} extend entity Topic {{ predicate mayEditWeb(w :: Web) {{ predicate mayEditWeb(w Web) extend entity Topic memberOf(w.acl.edit) acl -> ACL acl -> ACL memberOf(w.acl.edit) }} }} rules page topic(topic :: Topic) {{ rules page topic(topic Topic) mayViewTopic(topic) mayViewTopic(topic) data model }} rules page editTopic(topic :: Topic) {{ rules page editTopic(topic Topic) mayEditTopic(topic) mayEditTopic(topic) }} access control
  • Embedded Domain-Specific Languages DSL assimilate GPL GPL compile 'machine' 'machine' assimilate compile prog program program code code MetaBorg (OOPSLA'04) DSLs for abstraction over libraries/frameworks fine-grained interaction with 'host' code language conglomerates mix DSL and GPL code
  • Swing Userinterface Language import javax.swing.*; import java.awt.*; public class Test3 { public static void main(String[] ps) { JFrame frame = frame { title = "Welcome!" content = panel of border layout { center = label { text = "Hello World" } south = panel of grid layout { row = { button { text = "cancel" } button { text = "ok"} } } } }; frame.pack(); frame.setVisible(true); } }
  • DSL with embedded GPL Code assimilate compile 'machine' 'machine' assimilate compile code code provide GPL expressivity/coverage to complement DSL
  • DSL with embedded GPL Code vexp : dexp { $$.hi = $$.lo = $1; } | '(' dexp ',' dexp ')' { $$.lo = $2; $$.hi = $4; if( $$.lo > $$.hi ){ printf( "interval out of ordern" ); YYERROR; } } | dexp '*' vexp { $$ = vmul($1, $1, $3); } | vexp '/' vexp { if(dcheck($3)) YYERROR; $$ = vdiv($1.lo, $1.hi, $3); } Source: http://dinosaur.compilertools.net/yacc/index.html
  • Mixing DSLs: HQL in WebDSL function sortedBlogEntries(b : Blog) : List<BlogEntry> { var entries : List<BlogEntry> := select distinct e from BlogEntry as e, Blog as b where (b = ~b) and (e member of b._entries) order by e._created descending; return entries; }
  • Evolution
  • evolution scenarios DSL DSL DSL program program prog (model) (model)
  • regular evolution DSL DSL DSL DSL DSL DSL program program modify program program prog modify prog (model) (model) (model) (model) regular evolution: adapt software to new requirements implementation simply regenerated after modification of models
  • language evolution DSL DSL DSL program program prog (model) (model) evolve evolve language (syntax and/or transformations) evolve
  • model migration DSL DSL DSL DSL DSL DSL program program migrate program program prog migrate prog (model) (model) (model) (model) evolve evolve language evolution requires migration of models
  • platform evolution DSL DSL DSL DSL DSL DSL program program program program prog prog (model) (model) (model) (model) evolve evolve evolve evolve changes in the platform requires evolution of transformations
  • model extraction DSL DSL DSL DSL DSL DSL program program abstract program program prog abstract prog (model) (model) (model) (model) derive DSL programs from (legacy) GPL programs
  • abstraction evolution DSL DSL DSL program program prog (model) (model) abstract DSL DSL DSL program program prog (model) (model) develop higher-level abstractions
  • Coupled Evolution Data Data Data Data evolve evolve model model Model' Model' Data migrate Data' Data' Data migrate
  • Schedule ● Lab: implement your DSL ● Design 1: demonstrations Thursday and Friday ● Cases: grades coming up ● Lecture 13: Betsy Pepels from CapGemini ● Lecture 14: Johan den Haan & Michel Westrate from Mendix