Modellbaserad utveckling med UML 2.0 JOHAN SÄFSTRÖM Examensarbete Stockholm, Sverige 2010
Modellbaserad utveckling med UML 2.0 JOHAN SÄFSTRÖM Examensarbete i datalogi om 30 högskolepoäng vid Programmet för datateknik Kungliga Tekniska Högskolan år 2010 Handledare på CSC var Henrik Eriksson Examinator var Yngve Sundblad TRITA-CSC-E 2010:053 ISRN-KTH/CSC/E--10/053--SE ISSN-1653-5715 Kungliga tekniska högskolan Skolan för datavetenskap och kommunikation KTH CSC 100 44 Stockholm URL: www.kth.se/csc
Model driven development with UML 2.0 Abstract Within the software industry there has always been a strive for a higher degree of abstraction. At the very beginning software development was about having ones and zeros in the right sequences which was quite time consuming to say the least. FORTRAN was first out to help developers in the 1950 s. Much has happened after that. Different paradigms have evolved and disappeared during the passing of time. With the appearance of UML (Unified Modeling Language) and MDA (Model Driven Architecture) we have now reached the next level. There have been models supporting the software industry for ages, but it is not until now with UML 2.0 that we have reached a level where we can use the models themselves as a programming language. UML as a programming language is a subset of UML and is generally called Executable UML (xuml). The compiler tied to it is called a model compiler. The model compiler can be compared to an ordinary compiler with the difference that it takes an abstract form (model) and creates executable code straight from it. This of course puts high demands on the software tools, used for programming UML, containing the model compiler. Examples of such tools are Rational Rose RT and Telelogic Tau (now Rational Tau). I have had the opportunity to try the model driven approach in a reality-based test within a big telecom company. I used Telelogic Tau to create new code in UML for an already existing program that was originally developed in a traditional way in C. The question at hand is if the software industry is ready to move to model driven development and if this new paradigm has more benefits than drawbacks.
Modellbaserad utveckling med UML 2.0 Sammanfattning Det har inom mjukvaruindustrin alltid funnits en strävan efter en högre abstraktionsnivå. I allra första början handlade det om att strukturera upp ettor och nollor i rätt sekvenser, vilket var oerhört tidskrävande. FORTRAN var först ut med att hjälpa utvecklare under 1950-talet. Sedan dess det har det hänt mycket. Olika paradigm har uppkommit och passerat under tidens gång. I samband med uppkomsten av UML (Unified Modeling Language) och MDA (Model Driven Architecture) har vi nu nått nästa nivå. Det har funnits modeller inom mjukvaruindustrin sedan långt tillbaka, men det är inte förrän med UML 2.0 som vi har nått en nivå där modellerna själva kan fungera som ett programmeringsspråk. UML som programmeringsspråk är en delmängd av UML och kallas generellt för Executable UML (xuml). Kompilatorn som är kopplad till en xuml-modell kallas för en Model Compiler. Denna kan jämföras med vanliga kompilatorer med den skillnaden att den tar en abstrakt form (modell) och skapar körbar kod direkt ifrån denna. Detta ställer självklart stora krav på de verktyg som används för att programmera UML. Exempel på sådana verktyg är Rational Rose RT och Telelogic Tau (numera Rational Tau). Jag har haft möjligheten att pröva modellbaserad utveckling i ett verklighetsbaserat test hos ett stort telekomföretag. Jag använde Telelogic Tau för att skapa ny kod i UML för ett redan existerande program som ursprungligen utvecklats på traditionellt sätt i C. Den stora frågan är om mjukvaruindustrin är redo att gå över till modellbaserad utveckling, och om detta nya paradigm har fler fördelar än nackdelar.
1. Bakgrund.... 1 2. Vad är UML?... 2 2.1. Vilka olika sätt finns det att använda UML?... 3 2.2. Vad ingår i UML?... 6 2.3. Vad är skillnaderna mellan UML 1 och UML 2.0?... 6 3. Model Driven Architecture och Executable UML... 7 3.1. Model Driven Architecture... 7 3.2. Executable UML... 8 4. Kodgenerering... 9 4.1. Vad är kodgenerering?... 9 4.2. Vilka sorters generatorer finns det?... 9 4.3. Vilka är fördelarna med kodgenerering?... 10 4.4. Hur fungerar arbetsflödet vid kodgenerering?... 11 4.5. Vad kan man bygga med generatorerna?... 11 4.6. Vad finns det för baksidor med kodgenerering?... 11 4.7. Vilka typer av kodgeneratorer finns det?... 12 4.8. Hur är kodgenerering relaterat till computer-aided software engineering (CASE) och MDA?... 13 4.9. Är kodgenerering verkligen så effektivt?... 13 5. Prestandajämförelse... 14 5.1. Vilka verktyg finns det som använder UML och MDA?... 14 5.2. Metod prestandajämförelse... 14 5.3. Jämförelser... 15 5.4. Slutsats prestandajämförelse... 16 6. Praktiskt test... 17 6.1. Metod... 17 6.2. Tekniken Bakom... 17 6.3. Modellen i TAU... 17 6.4. Test i verklig miljö... 22 6.5. Omgivningen... 23 6.6. Sammanfattning av modellen... 24 6.7. Resultat... 25 7. Hur fungerar MDA/Executable UML jämfört med traditionell utveckling?... 25 Produktivitet... 26 8. Hur ser framtiden inom MDA och kodgenerering ut?... 28 Referensförteckning... 29
1. Bakgrund. Utveckling av stora program är kärnverksamheten i många stora företag. Det drar enorma kostnader och leder inte sällan till stora förluster när programsystem visar sig vara feltänkta (feldesignade). Programutvecklingsteknik och utvecklingsverktyg har därför blivit centrala frågor i företag. Denna rapport är ett bidrag till detta ständigt pågående arbete. Stora program modulariseras alltid för funktionalitet och flexibilitet. Modulerna kallas objekt och objekttyperna kallas klasser. För beskrivningen av klasser och deras samband finns standarden UML som ger en grafisk beskrivning med olika standardiserade diagramtyper. För att gå från UML-diagram till programkod och tvärtom finns flera avancerade och dyra verktyg. Min uppdragsgivare har nu ställt frågan om tiden är mogen för att gå över till UML2- baserade verktyg se om en introduktion av modellbaserad utveckling skulle kunna vara möjlig. Syftet med examensarbetet är att ta fram den information som behövs för att man skall kunna ta ett beslut angående om det finns UML2-verktyg som är tillräckligt bra och i så fall hur man skall gå tillväga för att skapa lättförståeliga och underhållbara modeller i detta verktyg. 1
2. Vad är UML? UML är en standard för design och modellering som har tagits fram av OMG (Object Modeling Group). Förutom UML är OMG mest kända för att ha tagit fram CORBA, standarden för kommunikation mellan distribuerade objekt. UML är en förkortning av Unified Modeling Language. Som namnet antyder är detta ett eget språk, som används för att beskriva och understödja allehanda mjukvarusystem, men särskilt de som är objektorienterade (OO). Enkelt uttryckt består det av en grafisk notation. Så här skriver OMG i UML Standard: The objective of UML is to provide system architects, software engineers, and software developers with tools for analysis, design, and implementation of software based systems as well as for modeling business and similar processes. - OMG Unified Modeling LanguageTM (OMG UML), Infrastructure Version 2.2 Det ursprungliga UML kom till redan 1997. Den första versionen kallades förvirrande nog för UML 1.1 eftersom den redan reviderats en gång av alla berörda parter. Efter detta har det funnits flera versioner med mindre ändringar, samt det stora steget till UML 2.0 som har varit det största hittills. UML 2.2 är den senaste utgivna standarden vid tidpunkten för denna rapport. Uppkomsten av UML härrör från unifieringen av de många objektorienterade modelleringsspråk som frodades under sent 1980-tal och tidigt 1990-tal. Anledningen till detta är logisk. Ingenjörskonst i allmänhet förenklas genom arbete med modeller. Det gäller i samma utsträckning för en arkitekt som för en mjukvaruutvecklare. Det har funnits olika typer av modeller inom mjukvaruindustrin under en längre tid. Huvudanledningen till detta är helt enkelt att programmeringsspråk i sig själva inte har en tillräckligt hög abstraktionsgrad, och för att skapa sig en överskådlig bild behövs någon form av modell. Dessa modeller har varierat kraftigt beroende på vad 2
som har varit det viktigaste för berörda utvecklare. Modellerna möjliggör vad man enkelt brukar kalla för mjukvarudesign, och de mest vanliga modellerna har förenats i UML (UML Distilled 2004, s.1). Exakt vad som UML används bäst till beror mycket på vem man frågar. UML har många olika domäner och detta kommer sig till största delen av att det är många olika aktörer som under årens lopp har haft olika krav och önskemål om interoperabilitet mellan olika system. De olika aktörerna har deltagit till att bygga upp UML till vad det är idag, och detta är en process som lever i allra högsta grad. Att så många olika parter har varit med och skapat UML har gjort att det finns ett brett spektrum på användande av språket. Modellerna ger generella fördelar, men synen på vad som leder till en effektiv utveckling av programvara går brett isär bland utvecklare världen över. Trots att modellerna har funnits inom mjukvaruindustrin länge är deras roll fortfarande mycket omdiskuterad. Detta beror till hög grad på hur olika personer använder modellerna och uppfattar UMLs roll. Det är just detta fenomen som är väldigt betydelsefullt och som denna rapport kommer att lägga mycket fokus på. 2.1. Vilka olika sätt finns det att använda UML? Vi har konstaterat att UML är brett omfattande och att nyttjandet av UML ser väldigt olika ut. Funderar man lite mer noggrant över texten på föregående sida om OMGs idé för vad UML ska vara, inser man att det är en hel ocean av tänkbara användningsområden. För att få någon form av överblick krävs det att man förenklar bilden av UML och ger användandet lite struktur. Vi behöver med andra ord se mer ingående på UMLs olika användningsområden. Fowler kategoriserar, i sin bok UML Distilled, in användandet av UML i tre olika huvudkategorier: Sketch (Skiss) Blueprint (Ritning) Programming language (Programmeringsspråk) 2.1.1. UML som skiss Fowler skriver vidare att UML till största delen används som sketch eller skiss på svenska. I denna grupp gör man helt enkelt bara enkla skisser över systemet, eller delar av detta, utan att gå närmare in på några detaljer. Innan vi går vidare kan det även vara bra att omnämna begreppen Forward/Reverse engineering. Med forward engineering avses här att man ritar UML-diagram innan man skriver koden. Reverse engineering är motsatsen, koden är redan skriven, men man bygger UML-diagram för att kunna förstå den bättre. 3
Forward engineering och reverse engineering är användbara både inom kategorierna sketch och blueprint. (UML Distilled 2004, s. 2). Att använda UML som skiss innebär att man är selektiv i sitt modellerande. Om man använder skissen för forward engineering så menas att man först skissar UMLdiagram och sedan programmerar utifrån detta. Det typiska användandet för skissen är som diskussionsunderlag inför en grupp inom utvecklingsteamet. Målet är att kunna måla upp och kommunicera idéer över det planerade arbetet. Diskussioner om koden kan uppstå, men rör då oftast bara de specifika delar som är särskilt viktiga eller svåra. (UML Distilled 2004, s. 2). I fallet med reverse engineering används skissen för att förklara hur delar av systemet fungerar. Man modellerar då endast de klasser som är mest intressanta och värda att diskutera innan man åter ger sig in i koden. Skissen är väldigt dynamisk och informell. Den är snabb och fungerar bra för samarbete. Det typiska mediet är en whiteboard, men skissen kan även vara en viktig faktor inom dokumentation, då den fokuserar mer på förståelse hos läsaren än att ge en komplett bild av verkligheten. Mycket av den UML som återfinns inom litteraturen är just i skissform (UML Distilled 2004, s. 2). En enkel sökning på Internet visar att det finns en uppsjö av enkla och bra verktyg för att skissa UML. 2.1.2. Blueprint Där skissen är enkel och dynamisk är blueprinten, eller ritningen, dess motsats. Den används för att beskriva systemet i sin kompletta form. Med denna ritning ska man enkelt kunna leverera sin kod, utan att stöta på några stora hinder. Vanligtvis är det en mer erfaren utvecklare som skapar ritningen, där utvecklingsteamet sedan får programmera utifrån denna. Vid reverse engineering skapas ritningen utifrån koden, och är en detaljerad förteckning av klasser och parametrar. Syftet är att få en bra och grafisk dokumentation som ska hjälpa utvecklare att förstå systemet (UML Distilled 2004, s. 3). Att skapa en ritning kan innebära att man inkluderar alla detaljer, eller så kan man nöja sig med att endast modellera en utvald del av systemet som en blueprint. En vanlig metod är att man skapar blueprints för sina subsystem, men när man kommer till mellanliggande gränssnitt överlåter man arbetet med att ta fram detaljerna i gränssnitten för utvecklarna (UML Distilled 2004, s. 3). Till skillnad mot sketch kräver blueprints mycket mer sofistikerade verktyg. Ursprungligen kallades dessa verktyg för CASE-tools (Computer Aided Software Engineering), men begreppet har under årens lopp fått negativa associationer och kallas därför sällan så numera. Verktyg som utför forward engineering skapar utförlig kod utifrån modellen. Reverse engineering sparar ut nödvändiga data ur koden och genererar diagram. Verktyg som klarar både forward/reverse engineering använder vad man kallar för roundtrip engineering och kallas för roundtrip tools (UML Distilled 2004, s. 3). 4
Gränsen mellan blueprint och sketch kan vara rätt suddig. Enkelt uttryckt är skissen avsiktligen ofullständig, och blueprinten är komplett. (UML Distilled 2004, s. 3). 2.1.3. UML som programmeringsspråk Ju mer man arbetar med konstruktion i UML, desto mindre lämnas kvar till sedvanlig programmering. Det vanliga arbetet blir då mer och mer mekaniskt och man kan dra slutsatsen att detta arbete också skulle kunna automatiseras. Många CASE-verktyg har någon form av kodgenereringsegenskaper. När man når den punkten att UML specificerar hela systemet, har man också kommit till den punkten att UML kan fungera som ett programmeringsspråk. I detta läge ritar utvecklaren UML-diagram och genererar körbar kod direkt utifrån modellen. För att detta ska vara möjligt krävs förstås mycket kraftfulla verktyg. Med UML som programmeringsspråk uttrycker UML-diagrammen exakt samma sak som den utifrån diagrammen genererade koden. Därmed talar man egentligen inte längre om roundtrip engineering eftersom diagrammen och källkoden betyder samma sak. För att förtydliga de olika sätten att arbeta med modeller använder jag mig av bilden nedan. De två ytterligheterna i diagrammet är Code Only och Model Only. I dagsläget torde Code Only vara det mest ovanliga sättet att arbeta, men det existerar säkerligen. Att skriva kod helt utan modell är garanterat inget en UML-förespråkare skulle rekommendera, och de flesta utvecklare använder nog någon form av modell. Model Only motsvarar användandet av UML som skiss, till exempel vid en whiteboard för att strukturera upp systemet och överföra idéer inom utvecklingsteamet. Det är här som UML har sitt största användningsområde i dagsläget (UML Distilled 2004: s. 2). 5
Vid enbart reverse engineering använder man koden själv som källa, och därifrån skapar diagrammen som en grafisk vy av koden. Verktyg som stöder detta är oftast intimt sammankopplade med programmeringseditorn där själva koden skrivs. Detta motsvarar Code Visualization i bilden. Roundtrip engineering är ett mellansteg där arbetet kan ske från två håll och hamnar därmed i mitten av diagrammet. UML som programmeringsspråk kategoriseras som modellcentrerad (Model-centric i bilden). 2.2. Vad ingår i UML? UML är väldigt omfattande och det går inte att beskriva dess innehåll i denna rapport. Jag hänvisar till OMGs hemsida www.omg.org för mer information om UML. Läsaren förutsätts känna till de vanligaste diagrammen (såsom Klassdiagram, Aktivitetsdiagram, Tillståndsmaskiner, Sekvensdiagram), och får läsa sig till mer information om de övriga. Jag kommer dock i nästa punkt ge en kort beskrivning av skillnaden mellan UML 1.x och UML 2 eftersom det har haft omfattande konsekvenser för innehållet i denna rapport. 2.3. Vad är skillnaderna mellan UML 1 och UML 2.0? Det finns ett problem i UML 1.x. Det är väldigt svårt att beskriva arkitektur och återanvändandet av komponenter, bara genom att använda själva standarden. Anledningen till detta är att klassdiagrammen beskriver egenskaper och samband för varje instans av en klass, och inte hur den används i en specifik applikation eller komponent. Detta medför att det är svårt att skapa plug-and-play arkitektur. I samband med UML for Real Time (UML-RT) som var en utbyggnad av UML så introducerades så kallade capsules. Dessa medförde återanvändbara arkitekturer i UML och är ett av fundamenten till ett annat viktigt OMG-initiativ, Model Driven Architecture (MDA), vilket jag beskriver i nästa kapitel. 6
3. Model Driven Architecture och Executable UML 3.1. Model Driven Architecture Som nämnts i föregående kapitel har en del mjukvarutillverkare valt att använda UML enligt en mer avancerad metod. Man har tagit steget bortom att vara ett enkelt modelleringsspråk till vad som kallas Model Driven Architecture (MDA). MDA är ett initiativ från OMG som betonar vikten av utveckling genom att transformera modeller (MDA Guide Version 1.0.1, 2004). I grund och botten är det ett standardiserat tillvägagångssätt för att använda UML som ett programmeringsspråk. Analys, design, implementation, byggande, färdigställning, debuggning och testning är allt gjort genom att skapa och definiera grafiska modeller, oftast men inte nödvändigtvis i UML. UML och MDA är tätt förknippade, men att man använder det ena betyder inte nödvändigtvis att man använder det andra och vice versa. Ett verktyg som implementerar MDA (Tex IBM Rational XDE) kan stödja multipla model-to-model-transformationer där modellen raffineras i varje steg. Ännu mer vanligt är verktyg som direkt transformerar en plattformsoberoende modell till en kvalitativ implementation. Exempel på detta är IBM Rational Rose RealTime, Pathfinder Solutions PathMATE och I-Logix Rhapsody. Enligt detta angreppssätt skapar utvecklaren en modell av systemet/applikationen och MDA-verktyget genererar en exekverbar fil eller ett bibliotek, till motsats från ett kodskelett. Delar av koden kommer ifrån tillstånd och transitioner i tillståndsmaskiner (state machines) samt klassoperationer, men den mesta delen av koden kommer direkt ifrån den grafiska modellen. Det kan vara så mycket som 90 % av koden, vilket i sig skvallrar om vilken fördel det blir att inte behöva skriva allt för hand. Det som krävs är att rita nödvändiga diagram och sedan generera koden. En annan fördel är att kvaliteten ökar. Detta kommer delvis från att den detaljerade koden som genereras implementerar begrepp som tillståndsmaskiner och objekthantering. Den genererade koden blir korrekt genom konstruktion (https://www.codegeneration.net/tikiindex.php?page=frequentlyaskedquestions). En annan mycket viktig aspekt ur utvecklarens synvinkel är fokus på en hög nivå systemets beteende. Genom att arbeta med modellen får man en högre grad av abstraktion (MDA Distilled 2004, s.2). Istället för att tänka på hur man ska skriva ett uttryck rent kodmässigt kan man istället fokusera på vilka konsekvenser en implementation får genom att titta direkt i modellen. Fokus ligger alltså på funktionaliteten och inte på hur man uttrycker sig rent syntaxmässigt. MDA delar upp utveckling i två huvudkategorier. Den första handlar om att för varje enskild applikation skapa en så kallad Platform Independent Model (PIM). PIM är en UML-modell som inte är beroende av någon särskild teknologi eller programmeringsspråk. I den andra delen används verktyg för att omforma PIM till en Platform Specific Model (PSM). Denna har en bestämd miljö som den ska köras i. Det är från PSM:en som den exekverbara koden sedan genereras. (Executable UML 2002, s. 11-12) För att förtydliga kan det vara bra med ett exempel: 7
Ponera att man ska bygga ett flygbokningssystem med hjälp av MDA. Man börjar då modellera sin PIM i något UML-verktyg. Det är tänkbart att man skulle vilja kunna använda detta system för olika plattformar, tex Java och C++. Följaktligen skapar man då två PSM:er med hjälp av något verktyg kapabelt att omforma PIM till PSM för dessa plattformar. Därefter kan ytterligare verktyg användas för att generera koden för båda plattformarna. 3.2. Executable UML Metoden ovan kan låta lite väl snårig och det finns verktyg som automatiserar hela processen, dvs att man går direkt från PIM till exekverbar kod utan några (för användaren synliga) mellansteg. Det är i just detta fall som UML är ett eget programmeringsspråk. Krävs det manuella ändringar i något mellansteg är vi tillbaka vid blueprint. En variant av detta är Steve Mellors Executable UML, förkortat xuml (Mellor and Balcer). Executable UML och MDA har mycket gemensamt. Skillnaden ligger i att i Executable UML går man direkt från PIM till ett färdigt system i ett enda steg via en så kallad Model Compiler. Det behövs alltså ingen PSM. Det är Model Compilern som gör att processen blir helt automatisk. Model Compilers bygger på användandet av arketyper i UML. En arketyp beskriver vad som ska göras med en Executable UML-modell och omforma denna till en specifik plattform. I fallet med flygbokningssystemet behöver man alltså två arketyper, en för Java och en för C++. Beroende på vilken av dem du kör mot din UML-modell får du en version av systemet som stöder just den plattformen. Executable UML använder inte hela spektret av UML. Alla diagram och delar i UML är inte nödvändiga för skapandet av Executable UML. Av den anledningen kan man säga att Executable UML bara är en delmängd av UML. Bilden nedan visar enkelt uttryckt skillnaden (Model Driven Architecture with Executable UML 2002, s 12.). 8
4. Kodgenerering Nu har jag beskrivit UML och MDA och vi har fått en bra uppfattning om hur det kan användas för kodgenerering. MDA är dock bara en av många metoder som använder kodgenerering. Därför vill jag belysa kodgenerering som ett mer allmänt begrepp. Anledningen till detta är att det är intressant ur ett framgångsperspektiv. Hur kommer MDA och Executable UML utvecklas i framtiden och vilka andra metoder finns det som redan har testats. Detta kapitel beskriver kodgenerering i allmänhet, dess olika tekniker samt fördelar och nackdelar. 4.1. Vad är kodgenerering? Kodgenerering är en teknik som handlar om att bygga kod genom att använda ett verktyg. Sådana verktyg kan vara allt ifrån enkla hjälpskript till storartade kreationer där abstrakta modeller av affärslogik blir till kompletta applikationer (Code Generation in Action 2003, s.3, 251). Ett annat vanligt exempel på generatorer som används idag är kompilatorer (Code Generation in Action 2003, s.27). Det finns ingen allmänt gällande definition på vad kodgenerering är; det kan vara allt från att köra ett enkelt kommando från att använda ett omfattande GUI, man kan bygga för ett eller flera programmeringsspråk på samma gång, och man kan bygga koden endast en gång eller multipla gånger. Det finns en oändlig variation av inputs och outputs. Det som är den gemensamma nämnaren är att output från generatorn är kod som en programmerare annars hade behövt skriva manuellt. 4.2. Vilka sorters generatorer finns det? Som nämnts tidigare finns det en oerhörd variation av generatorer men det finns två tekniker som på ett enkelt sätt delar in generatorer i två kategorier, passiv eller aktiv. Passiv kodgenerator. Dessa kodgeneratorer körs bara en gång när man är säker på att man har rätt inparametrar. Efter genereringen modifierar utvecklaren den genererade koden och på så sätt blir det inte längre någon fördel att generera koden på nytt. Ett vanligt exempel inom denna kategori är så kallade wizards där syftet är att utvecklaren ska få en flygande start. Aktiv kodgenerator. Kodgeneratorer inom denna kategori producerar kod som kan regenereras vid behov, till exempel under ett projekts gång. Den genererade koden modifieras aldrig av utvecklare eftersom fördelarna med aktiv generering då försvinner. Koden genereras på nytt varje gång förutsättningarna ändras. (The Pragmatic Programmer 1999, s.102). 9
Jämförelse mellan aktiv/passiv generator: Huvudskillnaden mellan aktiv och passiv består alltså i hur koden underhålls under ett projekts gång. Om kodgeneratorn är del i byggprocessen och den genererar ny kod vid varje ombyggnad så är det en aktiv generator. Om koden från samma generator modifieras av en utvecklare så hamnar den i kategorin passiv generator. Båda teknikerna kan spara tid och pengar men användningsområdet skiljer mycket (http://www.informit.com/articles/article.aspx?p=389718). Aktiva generatorer bygger kod som man inte ska modifiera, eller endast modifierar specifikt valda sektioner av koden som inte berörs av generatorn under regenereringscykeln. Passiva generatorer bygger koden en gång och sedan får man förbättra och underhålla koden därifrån. Passiva generatorer ger en initial fördel i produktivitet, men fördelarna med aktiva generatorer, där koden underhålls och buggar i mallarna kan motverkas och ändras i hela kodbasen, förloras i den passiva modellen (http://www.informit.com/articles/article.aspx?p=389718). 4.3. Vilka är fördelarna med kodgenerering? Kodgenerering är en mycket omdiskuterad metod inom mjukvaruutveckling. Det finns mycket som talar för kodgenerering, men även en del negativa aspekter. I stora drag kan man skriva ner fördelarna med kodgenerering i fyra punkter: Kvalitet: Kvaliteten hos koden som byggts av en generator är direkt relaterad till kvaliteten hos koden eller mallen som använts för att skapa målkoden. Om koden för generatorn eller dess mall förbättras och koden regenereras så kommer även målkoden förbättras (Code Generation in Action 2003, s.xvii,15). Konsistens: Målkoden som genererats av en kodgenerator är extremt konsistent. Namn på klasser, variabler och metoder byggs på samma sätt rakt igenom hela målkoden. Detta gör att målkoden är enkel att använda och gör det enklare att utöka funktionalitet (Code Generation in Action 2003, s.xvii,15). Produktivitet: Kodgeneratorer har potential att vara oerhört produktiva. Efter att man angivit de väsentliga inputparametrarna kan koden genereras på något ögonblick. Den riktiga fördelen med en kodgenerator kommer dock efter den initiala genereringen. Varje gång någonting i designen ändras så är det bara att generera om koden. Detta ger en stor fördel särskilt med tanke på att det är väldigt få projekt där kraven inte ändras under projektets gång (Code Generation in Action 2003, s.xvii,15). Abstraktion: Vissa generatorer bygger kod baserat på abstrakta modeller av målkoden. Till exempel kan man bygga ett SQL schema där definitioner av tabeller och fält med mera är representerade via XML. Inom MDA är denna höjning av abstraktion central 10
(MDA Distilled 2004, s2). Värdet av denna abstraktion är att till exempel att generatorn kan ställas om för att bygga kod för en annan plattform Code Generation in Action 2003, s.xvii,15). 4.4. Hur fungerar arbetsflödet vid kodgenerering? Standardflödet inom mjukvaruutveckling är editering-kompilering-test. Vi editerar koden och kompilerar den. Därefter genomförs tester för att se att programmet beter sig som tänkt. Måste man ändra någonting så repeteras flödescykeln till dess att man uppnått ett tillräckligt bra resultat. Arbetsflödet vid kodgenerering beror först och främst på om man använder aktiv eller passiv generering. Aktiva generatorer bygger kod som man inte modifierar, eller att man modifierar endast utvalda delar som generatorn inte tillåts ändra. Passiv generering bygger kod som man sen editerar till den grad man själv finner lämpligt. Arbetsflödet för en passiv generator blir alltså att man kör generatorn och sedan följer man standardflödet editering-kompilering-test därefter. Med aktiv generator kör du först genereringen och sen kompilering och test precis som vanligt. Vid problem i den genererade koden ändrar man mallen eller inputen till generatorn och regenererar. Är problemet i en eventuellt handskriven del som reserverats från generatorn så följer man det vanliga standardflödet för den delen (Code Generation in Action 2003, s.34-35). 4.5. Vad kan man bygga med generatorerna? Det finns generatorer för ett brett spektrum av system och applikationer. Generellt sett fungerar generatorer bra när man har stora problem som kräver stora volymer kod, exempelvis databasaccess och stored procedures, (Code Generation in Action 2003, s.25), men det går även att generera användargränssnitt och dokumentation (Code Generation in Action 2003, s.126-127). Affärslogik är ett område som där kodgenerering kan vara mer svårtillämpat (Code Generation in Action 2003, s.251). 4.6. Vad finns det för baksidor med kodgenerering? Liksom vilken annan teknik som helst finns det bra och dåliga sidor. Här följer ett par aspekter som man måste hantera för att det ska fungera effektivt: Rädsla för ny teknik: Introduktion av en kodgenereringsteknik möts ofta med rädsla och skepsis av de utvecklare som ska använda den. Det kan till exempel vara rädsla för att den nya tekniken ska göra ens jobb överflödigt eller motvilja mot förändring (Code Generation in Action 2003, s.23, 26, 35-36). Dokumentation: Kodgeneratorn behöver alltid dokumenteras, även om den är köpt från tredje part. Det behövs för att veta hur den fungerar i den existerande miljön och hur den ska underhållas (Code Generation in Action 2003, s.21). 11
Utbildning: För att utvecklare ska kunna använda den krävs också utbildning i det nya sättet att arbeta med generatorn och värdet av detta. (Code Generation in Action 2003, s.22-23). Underhåll: En kodgenerator innebär ännu ett verktyg i mängden av utvecklingsprogramvara. Det normala arbete med versionshantering och underhåll som brukar krävas gäller alltså även här (Code Generation in Action 2003, s.23). Komplexitet: Beroende på komplexiteten hos applikationen kan generatorn i sig bli komplex. Det gäller att försöka hålla generatorn användarvänlig för att användare ska nyttja den (Code Generation in Action 2003, s.26, 29), (Model Driven Architecture with Executable UML 2004, s33). Prestanda: För vissa kritiska sektioner av koden kan det behövas inlinekod för att få tillräckligt hög prestanda. (Executable UML 2002, s. 26),(Code Generation in Action 2003, s.79). 4.7. Vilka typer av kodgeneratorer finns det? Att skapa olika kategorier för kodgeneratorer är svårt. En metod är att se på input/output på generatorn för att se skillnader. När man tittar på input så kan man antingen ha kod eller någon abstrakt form som representerar designen. För outputsidan kan det vara inputkoden med endast vissa tillägg eller helt ny kod som helt och hållet implementerar designen och som inte kräver någon utökning. Baserat på dessa skillnader I input och output kan vi definiera olika typer av generatorer (Code Generation in Action 2003, s.28-29): Code Munger: En Code Munger läser kod som input och bygger ny kod som output. Den nya koden kan antingen vara partiell eller helt färdig beroende på designen hos generatorn. XDoclet är ett exempel på en Code Munger. (Code Generation in Action 2003, s.29). Inline Code Expander: En Inline Code Expander läser kod som input och bygger ny kod som använder inputkoden som en bas, men expanderar delar av koden, baserat på designen hos ursprungskoden. Embedded SQL-språk som tex Pro*C är exempel på inline code expanders. SQL skrivs in i C-koden och generatorn bygger den slutgiltiga koden genom att lägga in SQL in i C-koden. (Code Generation in Action 2003, s.30). Mixed Code Generator: Denna modell använder kod som input och genererar sedan ny kod genom att använda inputkoden som bas men returnerar outputkoden tillbaka till inputfilen. Wizards är ofta implementerade som mixed code generators. Kommentarer för de stycken som generatorn har lagt till är ofta inlagda i koden. (Code Generation in Action 2003, s.30). 12
Partial Class Generator: En Partial Class Generator tar en abstrakt definition som input och bygger outputkod som är delvis färdig. Användaren får själv fylla i den fulla informationen för metoder och underklasser. (Code Generation in Action 2003, s.31). Tier Generator: Denna typ av generator tar en abstrakt definition och skapar komplett kod utifrån denna. Koden som har genererats modifieras inte av användaren (Code Generation in Action 2003, s.32). 4.8. Hur är kodgenerering relaterat till computer-aided software engineering (CASE) och MDA? CASE-verktyg var vanliga i slutet av 80-talet och under tidigt 90-tal. Dessa verktyg påstods vara så kraftfulla att programmerarens roll skulle försvinna. Med hjälp av visuella verktyg och en generator skulle man enkelt bygga hela applikationer. Detta finns en klar parallell mellan gårdagens CASE-verktyg och dagens MDA-generatorer som kompilerar UML till exempelvis Java eller.net. Verktyg inom båda kategorierna använder en abstrakt beskrivning för att skapa kod med hjälp av en generator. För att knyta an till föregående kapitel bör nämnas att modellbaserad generering med UML är ett bra exempel på när man använder tier-generatorer (Code Generation in Action 2003, s.32). Inom MDA kallas som tidigare nämnts dessa generatorer för Model Compilers. Tekniken hos MDA/CASE-verktyg skiljer sig från övrig kodgenerering på så sätt att den fungerar ovanifrån-ner, och de flesta andra kodgenereringstekniker gör tvärtom, botten-upp. (http://www.codegeneration.net:443/tikiindex.php?page=frequentlyaskedquestions) 4.9. Är kodgenerering verkligen så effektivt? Som jag tidigare nämnt är det inte alls alla som anser att kodgenerering fungerar i praktiken. En fråga som ofta uppstår i de här sammanhangen är att om det är så fantastiskt effektivt att det bara är att trycka på en knapp för att generera körbar kod, varför gör då inte alla det. En som har reagerat på detta sätt är Paul Kimmel (UML Demystified 2005, s. 188): If somebody tells you that you are to model, model, model and flip a switch generating an executable, then flip that bozo bit. We are a decade or two away from the technology and education supporting generated applications. Min tolkning av detta är att modellering med kodgenerering sällan blir så enkelt som pro-anhängare säger. Det finns många hinder på vägen som gör att modellering med kodgenerering inte är så effektivt som en del vill få det att framstå som. 13
5. Prestandajämförelse Mitt arbete gick ut på att använda ett verktyg som var kapabelt att utifrån UML generera körbar kod. Därför gjorde jag en jämförelse mellan några MDA-baserade verktyg som jag hade tillgång till hos min uppdragsgivare. 5.1. Vilka verktyg finns det som använder UML och MDA? Idag översvämmas marknaden av verktyg som använder UML och MDA. Det finns dock en än så länge begränsad upplaga av verktyg som är kapabla att generera avancerad kod direkt ur UML-modellen. Några av de mest avancerade på området är Rational RSA, Rational Rose RT och Telelogic Tau (Numera Rational Tau). Det var även dessa tre som jag undersökte för möjlig tillämpning i mitt arbete. 5.2. Metod prestandajämförelse Mitt sätt att jämföra programmen är att skapa en lista med olika viktiga aspekter som programmet bör ha. Genom att sedan betygssätta varje aspekt och multiplicera med en viss vikt får man sedan ett värde för varje aspekt. Genom att sedan addera värdena kan man avläsa en slutsumma som man kan jämföra med de andra programmens slutsummor. Detta är en enkel metod som såklart kan missbrukas för att ge vinklade slutsatser och därför bör man också komplettera med en diskussion kring resultaten. De aspekter (med vikter) som är lämpliga för avdelningen att ta med har jag fått av min handledare på företaget och dennes chef. Se diagrammet nedan för att de olika aspekterna och deras individuella vikter. Prioritet 6 5 4 3 Prioritet 2 1 0 Utseende Snabbhet Pålitlighet Utvecklade kringsystem Kompabilitet yttre Kompabilitet inre Kodgenerering Figur 1. Som figuren visar har jag valt att sätta vikter ända upp till nivå 5. Detta har som följd att aspekter med värde 5 får väldigt stort utslag i det totala värdet som visas i figur tre 14
nedan. Det är dock helt avsiktligt då vissa aspekter är avgörande för hur möjligheterna till att arbeta med något av verktygen är. Viktigast är bra kodgenereringsegenskaper och näst viktigast är pålitlighet. 5.3. Jämförelser Det slutgiltiga resultatet fick jag fram genom att intervjua utvecklare som arbetar med de olika verktygen. Då antalet intervjuade personer inte var särskilt stort och själva användandet skilde sig mellan utvecklarna blev dock resultatet för litet för att ge en tillräckligt bra helhetsbild. Utifrån den information jag fick kunde gjorde jag ändå ett försök till sammanställning som syns i figur 2 nedan. 6 5 4 RSA 3 Rose RT 2 TAU 1 0 Utseende Snabbhet Pålitlighet Utvecklade kringsystem Kompabilitet yttre Kompabilitet inre Kodgenerering Figur 2. Den visar de olika verktygens individuella betyg i de olika aspekterna. Vad som är anmärkningsvärt här är skillnaden i kapacitet för kodgenerering. RSA klarar inte att generera kod på samma sätt som Rose RT och är inte i närheten av TAU. Rose RT är inte heller lika avancerat som TAU och det kommer till stor del av att Rose RT inte stöder UML 2.0. Konsekvensen består helt enkelt i att man arbetar på olika abstraktionsnivåer. Med TAU arbetar man helt i sin UML-modell och när man är klar gör man en kodgenerering som resulterar i en körbar kod. I RSA arbetar man fram en modell som man genererar ett kodskelett ur. Detta skelett är endast uppbyggt av klasser och funktioner och innehållet måste man fylla i själv. Rose RT fungerar som ett mellanting. Man kan arbeta på en hög nivå i modellen, men det krävs att man gör vissa delar i handskriven kod. Det uppstår då en skillnad i abstraktionsnivå och kan göra att man har svårare att avgöra var ett fel uppstår i modellen eller i den handskrivna koden (Code Generation in Action 2003, s.79). Slutresultatet visas här i figur 3. Oavsett betygsmodellen så hade TAU uppenbarligen varit det enda rimliga alternativet av dessa tre. 15
100 90 80 70 60 50 40 30 20 10 0 Utseende Snabbhet Pålitlighet Utvecklade kringsystem Kompabilitet yttre Kompabilitet inre Kodgenerering Summa RSA Rose RT TAU Figur 3. På det hela taget så är TAU klart bäst och detta beror till väldigt stor del på den avancerade kodgenereringen. Oavsett vad den här betygsmodellen säger så bör man föra en diskussion kring de olika verktygen. Det som gör den största skillnaden är som sagt kodgenereringen. Skillnaderna mellan programmen är så stora att vi egentligen hade klarat oss utan betygsdiagrammen. Det är nämligen en avsevärd skillnad i teknologi där det för användaren framförallt är graden av abstraktion som skiljer. I TAU kan användaren arbeta fullständigt i sin UML-modell och behöver därför inte lämna denna högre språknivå. Saker som automatisk felkorrigering, felsökning och debuggning underlättas därmed kraftigt. 5.4. Slutsats prestandajämförelse Efter genomgången med prioriteringsmodellen faller mitt val av verktyg på TAU. Det finns även andra aspekter som jag inte tidigare nämnt som till exempel möjligheten till val av programspråk. Avdelningen arbetar nästan helt i C och TAU är den enda av dessa tre som kan generera C-kod. Därför hade kanske valet fallit på TAU om man inte samtidigt tänker byta programmeringsspråk. Om man dock skulle vilja byta stöder alla tre verktygen både C++ och JAVA. Nackdelarna med TAU är att det än så länge inte stöder formatet EMF för utbyte av UML-modeller mellan olika program samt att det kräver mycket goda kunskaper i UML och i verktyget själv. 16
6. Praktiskt test 6.1. Metod Det kan vara svårt att avgöra hur bra ett verktyg för att generera kod är genom att bara göra enkla tester. Därför har jag valt en lite mer avancerad approach för att analysera detta problem. Tanken var att jag skulle utveckla programvara till ett redan befintligt och inte särskilt omfattande delsystem med hjälp av verktyget TAU. Detta för att kunna se hur resultatet blev (jämfört med redan befintlig programvara) med hjälp av denna alternativa utvecklingsmetod. Programvaran för systemet kallas IPSyncRegi och är ett enkelt interface med en server och klient och ett antal olika signaler däremellan. Fördelen med att välja IPSyncRegi är att det är ett högst aktuellt exempel på en programvara som utvecklats på avdelningen samt att det finns en tillhörande simulator för systemet vilket möjliggör testning av den genererade koden. 6.2. Tekniken Bakom Vad måste man ha med för att kunna göra en kodgenerering? I exemplet med IPSyncRegi som beskrivs mer detaljerat nedan får man svar på dessa frågor samt hur det fungerar att koppla den genererade koden mot OSE och avdelningens byggmiljö. IPSyncRegi IPSyncRegi är som nämnts ett enkelt interface som sitter mellan olika kort i en basstation. Det har en server och en eller flera klienter och mellan klienterna och servern går det en mängd olika signaler. Serverns respektive klienternas handlingsschema bygger på tillståndsmaskiner. Nedan följer en beskrivning av de viktigaste delarna för systemet i verktyget TAU. 6.3. Modellen i TAU UML-Modellen för IPSyncRegi i TAU är relativt enkel. Den har egentligen bara en aktiv klass och det är Server. I mitt exempel nedan ingår dock även en klass för Client eftersom jag ville kunna simulera även denna i modellen. Vid själva kodgenereringen hade jag dock bara Server-klassen och ett externt interface vilket beskrivs längre fram. Utöver klasserna för Server och Client har jag även en huvudklass för programmet som jag kallat IPSyncRegi som även den är aktiv, eftersom dess underklasser är aktiva. Notera de dubbla ramarna på klassernas lodräta sidor i exemplet nedan. Det är markeringen för aktiv klass i UML2. 17
Klasserna Server och Client är anslutna via var sitt interface IServer och IClient. Tillsammans bygger dessa upp ett protokoll. Jag har även in lagt in definitionen för denna koppling i klassdiagrammet. 18
Varje aktiv klass är också försedd med ett tillståndsdiagram (State machine) som beskriver systemets beteende i olika lägen. Här är tillståndsdiagrammet för Serverklassen Varje rektangel med rundade hörn i bilden nedan beskriver ett tillstånd: Tillstånden ändras via signaler. Vilken typ av signal det är beror på om pilen pekar inåt (insignal) eller utåt (utsignal). TAU har implementerat signalerna på det här sättet så att man enkelt ska kunna specificera vad som leder till ett nytt tillstånd direkt i tillståndsdiagrammet. 19
Motsvarande tillståndsdiagram för Client-klassen ser ut på följande vis: Flödet för klienten är självfallet annorlunda. I övrigt är det ingen större skillnad gentemot tillståndsdiagrammet för Server-klassen. Den enda uppenbara skillnaden är att insignaler med samma namn här är representerade som utsignaler och vice versa. Tillståndsdiagrammen når man enkelt genom att klicka fram dem under respektive klass i modellvyn. 20
Allting i diagrammen finns även representerat i modellvyn. Objekt är därför lätta att återanvända, och verktyget kopplar själv till rätt objekt om man återanvänder namn. Samma objekt kan förekomma på flera ställen, beroende på om de har många kopplingar till olika element. Ändrar man ett objekt någonstans ändras samma objekt i hela modellen. 21
Vilka signaler som finns tillgängliga har jag definierat i ett komponentdiagram. Detta innehåller information om vilka signaler som ska finnas tillgängliga i interfacet. package SyncRegi SyncRegi Component Diagram {2/4} <<interface>> IServer signal INITIATE_MEMORY () signal IPAC_IP_SYNC_REGI_SERVER_UP_IND ( IpacIpSyncRegiServerUpInd) signal IPAC_IP_SYNC_REGI_SERVER_DOWN_IND ( IpacIpSyncRegiServerDownInd) signal IPAC_IP_SYNC_REGI_UNPUBLISH_IND ( IpacIpSyncRegiUnpublishInd) signal IPAC_IP_SYNC_REGI_INITIATE_SERVICE_CFM ( IpacIpSyncRegiInitiateServiceCfm) signal IPAC_IP_SYNC_REGI_INITIATE_SERVICE_SUS ( IpacIpSyncRegiInitiateServiceSus) signal IPAC_IP_SYNC_REGI_INITIATE_SERVICE_REJ ( IpacIpSyncRegiInitiateServiceRej) signal IPAC_IP_SYNC_REGI_TERMINATE_SERVICE_CFM ( IpacIpSyncRegiTerminateService Cfm) signal IPAC_IP_SYNC_REGI_AUDIT_CFM ( IpacIpSyncRegiAuditCfm) <<interface>> IClient signal IPAC_IP_SYNC_REGI_INITIATE_SERVICE_REQ ( IpacIpSyncRegiInitiateServiceReq) signal IPAC_IP_SYNC_REGI_TERMINATE_SERVICE_REQ ( IpacIpSyncRegiTerminate ServiceReq) signal IPAC_IP_SYNC_REGI_AUDIT_REQ ( IpacIpSyncRegiAuditReq) signal IPAC_IP_SYNC_REGI_AUDIT_READY_IND ( IpacIpSyncRegiAuditReadyInd) Signalerna kan med fördel även beskrivas i ett sekvensdiagram om man vill få en överblick i vilken ordning de skickas. Jag har dock inte gjort det här. 6.4. Test i verklig miljö För att verkligen kunna testa systemet i den verkliga testmiljön där det redan existerade en textbaserad klientsimulator tog jag bort Client ur modellen och sparade bara Server. Serverklassen är här även försedd med ett externt interface. Detta är för att Serverklassen ska kunna kommunicera med omgivningen. Interfacet finns inbyggt i TAU och kallas ENV. Hur det fungerar beskrivs nedan. Kvar i klassdiagrammet fanns följande: Klassen Server med en port och det externa interfacet ENV. 22
6.5. Omgivningen Då utvecklingen av kod inte längre är lika ansträngande kan omgivningen och integrationen bli den del i utvecklingsprocessen som blir mer komplicerad. Detta beror till största del på att man vill kunna kommunicera med omgivningen på något sätt. Utan omgivning har inte systemet någon större mening. Som man kan se i modellen nedan måste man från modellen gå genom skiktet ENV för att kunna nå omgivningen. ENV är alltså ett slags lager som tar in signaler från modellen och översätter dessa till signaler som omgivningen kan förstå. 23
För att det här ska fungera måste man programmera den här översättningen själv vilket är naturligt då omgivningen kan variera och det i dagsläget vore omöjligt att göra en kodgenerator som stöder alla typer av omgivningar. Problemet kvarstår dock att man måste arbeta traditionellt i det här skiktet. Det behöver dock inte vara särskilt komplicerat. Det genereras så kallade environment-filer vid kodgenereringen som innehåller alla signaler från UML-modellen. Till dessa finns en annan väldigt viktig fil - env_defs.h. I denna överför man i en while-loop UML-signalerna till motsvarigheter i omgivningen. ENV är i mitt exempel ett interface mot realtidsoperativsystemet OSE ( Operating System Embedded ), men det skulle kunna vara något helt annat, till exempel ett databasinterface, eller någon annan omgivning som inte kan modelleras (Executable UML 2002, s.30). 6.6. Sammanfattning av modellen Utöver de diagram som jag har beskrivit ovan behövs bara två saker för att kunna generera körbar kod. Den första är en tråd för servern men i det fallet att man endast har en aktiv klass så finns det alltid en implicit inlagd tråd i TAU. I min modell är den dock angiven för syns skull. Det andra som behövs är en artefakt. Denna är knuten till någon form av kompilator. I min modell har jag två artefakter. Den ena är kopplad till en AgileC-kompilator och den andra är knuten till Model-Verifier som är en inbyggd testsimulator. Artefakterna är angivna i ett Deployment Diagram på detta sätt: package SyncRegi SyncRegi Deployment Diagram {3/4} <<artifact,'agilec Code Generator'>> AgileC t1 <<artifact,thread>> mythread1 <<manifest>> IPSyncRegi <<manifest>> <<artifact,'model Verifier'>> ModelVerifier t2 <<artifact,thread>> mythread2 För att sammanfatta kort: De element som krävs för kodgenerering i TAU är: Klassdiagram med minst en aktiv klass, tillståndsmaskin till den aktiva klassen, tråd kopplad till den aktiva klassen 24
samt en artefakt kopplad till den aktiva klassen. Man kan direkt dra slutsatsen att man inte behöver hela UML för att kunna generera kod. Det räcker med en delmängd av UML. Exakt vilka delar som ingår för Executable UML är inte i dagsläget definierat (Executable UML 2002, s9.). Varje tillverkare bestämmer själv vilka element som måste ingå. Det som jag har räknat upp ovan är alltså det som gäller för TAU. Vill man ha flera aktiva klasser går det bra men man behöver då också ha flera trådar en för varje. Dessutom behövs även en tillståndsmaskin för varje aktiv klass. Denna kan dock vara väldigt enkel. Man kan också binda en artefakt till flera aktiva klasser. Givetvis finns det många andra användbara diagram och TAU stöder UML 2.0 fullt ut. Exempel på sådana andra diagram är: Use Case-diagram, Sekvensdiagram, Compostite Structure-diagram och Aktivitetsdiagram. Har man ett väldigt stort system kan det bli förvirrande att beskriva alla interface och kopplingar i ett klassdiagram. Då kan man med fördel använda ett Composite Structure-diagram. 6.7. Resultat Efter kompilering finns det ett fungerande IPSyncRegi. Servern svarar på de signaler man skickar och hanterar de nödvändiga parametrarna. Även om den nya genererade koden inte har någonting gemensamt med den ursprungliga, handskrivna koden är systemets funktioner likadana: Det har fungerat väl att modellera, generera, inkludera omgivningen, och att använda de genererade filerna i byggmiljön. 7. Hur fungerar MDA/Executable UML jämfört med traditionell utveckling? Det är inte det fungerande programmet i sig som är intressant utan det är vägen dit. Jag har utan några större förkunskaper använt en alternativ utvecklingsmetod genom att skapa en modell, gjort kopplingar mot OSE, samt byggt ihop med byggmiljön och den existerande simulatorn. Detta tyder på att modellbaserad utveckling och kodgenerering är ett effektivt sätt att arbeta. Det kan tyckas som att man tar väldigt god tid på sig i början men när väl modellen är klar så går allting väldigt fort. Min åsikt är att det antagligen hade tagit mig längre tid att utveckla IPSyncRegi på traditionellt sätt, och man skulle då också förlora den fördelaktiga översikt och dokumentation som modellen ger. Exemplet med IPSyncRegi visar att det är möjligt att redan idag att generera körbar kod direkt ur modellen. Trots detta har jag svårt att se att MDA /Executable UML kommer att få ett stort genombrott i den närmsta framtiden. 25