Model Driven Development and Code Generation
This discussion is crafted for small teams within medium-sized workgroups aiming to streamline processes through model-driven development (MDD). It emphasizes the importance of quality and efficient document management while addressing common challenges such as maintaining documentation synchronization and managing staff turnover. By linking modeling to code generation, teams can significantly reduce overhead and enhance system maintenance. Explore tools and approaches for effective code generation while balancing quality and accuracy in a collaborative development environment.
Model Driven Development and Code Generation
E N D
Presentation Transcript
Model Driven Development and Code Generation Make the Model Do the Work Chip Temm
Target Audience • Small Teams in Medium-sized Workgroups • Established processes • Discussion • Light process and tooling to produce rapid results and reduce overhead of new projects & system maintenance. • Model driven as differentiated from database-driven. • Linking modeling to code generation. • Not describing MDA. • Forward looking – not all of what is discussed exists
Where I’m Coming From • Managing matrixed development teams • Quality is key • Process matters • Trying to find balance between quality and accuracy • Understanding team drivers
MDD can help teams improve Maintenance Documentation Development Design
Documentation • Challenge: Getting code documented • Challenge: Keeping docs in sync • “Painful, boring, tedious” • Who is it for? • De-prioritized • Important • Memory Reallocation • Staff Turnover • HBAB
Document the Design • Makes less sense to document after the code is done • Model Metadata: • Communicates the original intention of the concepts modeled • Drives / can be derived from component metadata
Design • Design docs as communication • Reduce code-as-you-go • Enable better re-use
Development • Forward generate the repetitive • Enable easier distribution of work • Outlined development
Maintenance • Forward-generating new components is easier when you can see the rest of the model. • Know the ramifications of what you change • Refactoring can be easier: metaprogramming • … or at least no harder: round-tripping is a challenge. • Help get unit tests framed up
Using modelling tools. • Tools overview • Approaches to generation • Exporting to XMI • Tool-based generation
Tools Overview • Most UML modeling tools now support code generation • Java is a key target • ColdFusion not supported out of the box • Most tools export to XMI • Some have extended XMI • Different flavors
Sampling of tools • Tigris.org • ArgoUML -opensource • SparxSystems • Enterprise Architect- $200 • Gentlesoft • Poseidon- $900 (cfcxmi plugin)
Approaches to generation • Write your own generator • Modify a tool’s generation templates
Exporting to XMI • Pros: If you want to • write your own generators • pick your language • Modeling independence (ish) • Cons: • XMI is not the most readable • You do the heavy lifting
ModelGlue Transformation <?xml version="1.0" encoding="UTF-8" ?> - <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="no" /> - <xsl:template match="/"> <cfset listEvent = viewstate.getValue("myself") & viewstate.getValue("xe.list") /> <cfset commitEvent = viewstate.getValue("myself") & viewstate.getValue("xe.commit") & "& <xsl:value-of select="object/name" /> Id=" & urlEncodedFormat(viewstate.getValue(" <xsl:value-of select="object/name" /> Id")) /> <cfset <xsl:value-of select="object/name" /> = viewstate.getValue("
Example CF Char Sub Transform … «cfstoredproc procedure=“#currentTable#_Insert" datasource="$application.datasource$" » <cfloop collection="#currentcfc.properties#" item="thisProp" > «cfprocparam value="$variables.instance.#thisProp#$" type="In" /» </cfloop> «cfprocparam variable="objectID" type="Out" /» «/cfstoredproc» «cfset variables.instance.objectID = objectID /» «cfreturn variables.instance.objectID/»
CF Parsing of XMI <cfscript> xmlDoc = xmlparse('OpenModel.xmi'); classes = xmlsearch(xmlDoc,"//UML:Class[@xmi.id]"); classesLen = arrayLen(classes); for(i=1;i lte classesLen;i=i+1){ thisClass = classes[i]; //now loop down into properties, methods and arguments } </cfscript>
Using tool-based generation • Pros: • Tool does heavy lifting • Results are rapid • Toolset easily sharable • Cons • May have to learn a new language to write your templating logic • Create your own datatypes… • Vendor lock-in
Poseidon template macro • See Eclipse…
Generating to frameworks • Frameworks are geared toward driving code into patterns • Repetition is a good target for automation • Some existing frameworks have generation capabilities but are not model-first • Generate those ORM files from models
Converting Code to Models • Why? • Code needs to have reliable metadata • Reflection can be used to extract information • Layout of diagrams is no fun
Challenges to MDD • Technology • Round-tripping • Mindset • Management
Challenge: Technology • Commercial pkgs geared toward • Larger shops • Mainstream languages • Can be expensive • Learning curve • Getting lost in the feature set
Challenge: Round-tripping • ColdFusion not XML compliant, hard to parse • Flex is probably a good target • Version control
Challenge: Developer Mindset • Fear of ‘wizards’ • Fear of change • Fear of oppression
Challenge: Management • Requires investment • How many people do I have to train? • What processes do I have to change? • What will toolchain changes cost? • Where to allocate the risk of change?
Good Luck! Presentation will be available later today at: http://anthrologik.net/presentations/ dc_frameworks_2007_02_01.ppt Email: chip@temm.net http://del.icio.us/chiptemm/ http://cfdj.sys-con.com/author/temm.rss
Article COMPONENTNAME e.g."XMI_Parser"[ name [string] displayname [string] hint [string] PROPERTIES[ PROPERTYNAME[ name [string] type [string] required [BOOLEAN] displayname [string] hint [string] default [string] ] ] FUNCTIONS[ FUNCTIONNAME[ string name [string] access [string] returntype [string] roles [string] hint [string] output [BOOLEAN] ARGUMENTS[ ARGUMENTNAME[ name [string] type [string] required [BOOLEAN default [string] hint [string] ] ] ] ]]