1. Introduktion Refaktorisering och UML med Eclipse Eclipse är en utvecklingsmiljö för allehanda uppgifter. Den innehåller bland annat ett mycket kvalificerat stöd för programutveckling i Java. Den är särskilt lämplig för denna kurs eftersom det är lätt att göra designförändringar och det finns integrerade verktyg för design med UML. Eclipse är utformat som ett ramverk så att man enkelt kan lägga till ny funktionalitet med stickproppar (plug ins) som man kan hitta på nätet eller skriva själv. Propparna innehåller i regel kompilerade Java klasser som implementerar gränssnitt i ramverket. Det kommer löpande nya versioner av Eclipse och proppar som inte alltid fungerar tillsammans. Även Java miljön ingår i systemet som stickproppar. I denna laboration skall du använda en stickpropp för UML-modellering. Du kan även installera denna i Eclipse på din egen dator hemma. 2. Installation i C524 och hemma Det finns många Eclipse-baserade verktyg för att modellera med UML, se t.ex. http://marketplace.eclipse.org/. Beskrivningen i detta dokument använder Papyrus https://eclipse.org/papyrus/. Papyrus stöder UML och erbjuder möjlighet att grafiskt editera olika typer av UML-diagram. I den här laborationen kommer vi främst att titta på klassdiagram och utifrån dessa generera Javakod och omvänt generera klassdiagram utifrån Javakod. Det räcker för användning i denna kurs. Det är tillåtet att använda valfritt datorbaserat verktyg för att producera UML-diagram. Till exempel kan du titta på umletino eller community-versionen av Visual Paradigm. Båda dessa verktyg tillhandahåller också UML-modellering. De saknar dock kodgenerering till Java. Har du synpunkter på Papyrus eller hittar något annat verktyg som är riktig bra får du gärna tipsa oss. För att kunna använda UML-verktyget behöver du konfigurera Eclipse. I studentsal C524 är denna konfiguration redan genomförd. Hemma kan du följa nedanstående beskrivning för installation på din egen dator. Jag utgår från att du har Eclipse (Mars) installerad. Under menyalternativet Help->Install new software skall du lägga till två sajter (enklast via Addknappen): Papyrus uppdateringssajt http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/mars QVTO updateringssajt - http://download.eclipse.org/mmt/qvto/updates/releases/3.5.0/ Installera först allt under papyrus sajt och därefter allt under QVTO. Starta om eclipse. 3. Först lite om Eclipse 1. Java-editorn Standard-editorn för Java kan väldigt mycket om språket och rapporterar hela tiden fel och är beredd att hjälpa till på olika sätt. Fel markeras med vågstrecksunderstrykning och ett erbjudande om hjälp indikeras med en liten glödlampa i vänsterkanten. Om man skriver början på ett reserverat ord eller ett namn och därefter CTRL-mellanslag så kommer editorn att föreslå ett antal alternativ. Efter wh ges fyra alternativ för while-satser och några klassnamn som du förmodligen inte hört talas om. Genom att flytta sig till alternativen kan man få se hur Eclipse kommer att komplettera. Man accepterar med return eller dubbelklick. Editorn känner också till namn på dina egna variabler, metoder och klasser. 1
Man kan skriva main och få en hel main-metod och sysout för System.out.println(). Mallarna finns i Eclipse -> Inställningar -> Java -> Editor -> Templates där man själv kan modifiera och lägga till. När man skriver en punkt efter ett objektnamn erbjuds också ett antal alternativ. Antalet reduceras allteftersom man skriver vidare. Om man skriver x=1; utan att ha deklarerat x visar editorn en liten lampa som erbjuder att deklarera en lokal variabel, lägga till ett attribut eller en parameter. När lampan är dekorerad med ett litet kryss finns det fel som måste åtgärdas. Ett utropstecken betyder ofta att något är onödigt och kan tas bort utan att programmets funktionalitet förändras. Genom att klicka på lampan kan man ofta få upp förslag på åtgärder. 2. Menyer och genvägar Det finns ofta flera sätt att anropa en operation. De flesta operationerna kan nås via huvudmenyerna, File, Edit, etc. Många av operationerna förutsätter att man markerat det element som skall påverkas. Om man inte gjort kan alternativet vara nedtonat eller saknas. En del operationer har egna ikoner under raden med huvudmenyer. Editorer och vyer har ofta egna verktygsikoner. Genom att högerklicka på ett element öppnar man elementets kontextmeny. Om man vill att operationen skall gälla alla element i editorn skall man se till att inget element är markerat och högerklicka i bakgrunden. En del kommandon har tangentbordsgenvägar. Sådana syns till höger i vanliga menyer. Mycket går att konfigurera efter eget tycke, t ex via Eclipse -> Inställningar -> General ->Keys.... Inställningar kan sparas, exporteras och importeras. 3. Source-menyn Med Source -> Format formateras programmet så att indenteringen, inskjutna mellanslag, tomma rader etc. blir konsekvent. Det går att i detalj styra hur detta skall gå till i Eclipse -> Inställningar -> Java -> Codestyle -> Formatter om man inte är nöjd med standardvärdena. Medlemmarna i en klass (attribut, metoder, klasser etc.) bör vara ordnade på samma sätt i alla klasser i ett projekt. Med Source -> Sort members åstadkommer man detta i en klass, ett paket eller i hela projektet. Via Eclipse -> Inställningar ->Java ->Appearance -> Member Sort Order kan man styra detaljer för sorteringen. När man behöver en ny konstruerare som ger värden åt några attribut använder man med fördel Source -> Generate -> Constructor using Fields. Source -> Organize imports sorterar import-klausuler, tar bort onödiga och lägger till sådana som behövs. Med Source -> Clean Up... får man en mer genomgripande städning av programmet med indentering, sortering, mm. Detaljerna kan styras via Eclipse -> Inställningar -> Java -> Code Style -> Clean Up. 4. Refactor-menyn Refactor-menyn innehåller mängd operationer för att omstrukturera programmet. Innehållet i menyn växlar efter vad som är markerat i Package Explorer eller editorer. Namnbyten, Refactor -> Rename..., är en enkel och kraftfull operation. Om man byter namn på en klass kommer alla referenser till namnet i hela projektet att bytas ut. Om man så önskar kommer även liknande namn på attribut och metoder och förekomster i kommentarer att modifieras. 2
Det enklaste sättet att flytta klasser mellan olika paket är att dra dem i Package Explorer. Det går att flytta metoder och attribut på samma sätt, men det kräver ofta efterarbete. I uppgiften nedan får du prova några andra operationer. Experimentera gärna; i regel går det att återställa programmet med Edit -> Undo. 4. Papyrus UML I menyn Window -> Perspective -> Open perspective -> Other kan du välja ett anpassat perspektiv (Papyrus) för din modellering. Det går också bra att använda ditt vanliga Java perspektiv och öppna de relevanta vyerna separat i menyn Window -> Show View. Du behöver i så fall öppna Papyrus/Model Explorer och General/Properties. - När man arbetar med Papyrus (till exempel i uppgiften nedan) så kan det vara bra att känna till ett par allmänna saker. UML är ett generellt modelleringsspråk och saknar därför en del Javaspecifika konstruktioner. Därför behöver vi ange att den UML modell vi skapar skall vara Javaspecifik om vi vill kunna generera Javakod. Genom att ange Java som profil för projektet kan vi lägga till stereotyper till de olika elementen i modellen. Dessa stereotyper styr sedan vilken kod som genereras. - UML-modellen är integrerad med Java-representationen av programmet så att förändringar i den ena avspeglar sig i den andra. Du väljer själv om du vill synkronisera (dvs. skriva över) existerande filer eller generera nya javafiler respektive UML-modeller. För att generera Java kod, högerklicka på elementet i modellen och välj Java -> Generate Java Code. För att generera UML kan du istället högerklicka på klassen eller paketet i Project Explorer och välja Java -> Java Reverse. Det är inte alltid så lätt att få diagrammet att se ut exakt som man skulle önska. Ansträng dig inte mer än att diagrammet blir användbart som underlag för designdiskussionen. Tutorials: (http://wiki.eclipse.org/java_reverse_engineering) Uppgift Eclipse och Papyrus Denna uppgift innehåller enkel objektorienterad design och introducerar de viktigaste handgreppen i Papyrus. 1. Starta Eclipse. 2. Eventuellt installera och konfigurera UML-verktyget (enligt avsnitt 2). 3. Skapa ett nytt Papyrusprojekt (projektnamn: geometrypapyrus, modellnamn: geometryuml, och namn på rotelement geometry ). Välj UML som modelleringsspråk och välj typ klassdiagram. Lägg till Java som profil (finns bland registrerade profiler). 4. Importera Javas primitiva typer. I vyn Model Explorer högerklicka på rotelementet (geometry) och välj Import -> Import registered package. 5. Skapa klassen Point i UML-diagrammet genom att markera Class i UML-paletten och klicka på den plats i diagrammet där klassrutan skall placeras. Högerklicka i diagrammet och välj Show properties view ifall du inte ser en tabb där du kan ändra namn etc på klassen. 6. Lägg till två privata attribut, x och y, av typen double. Dra två Property element från paletten till din klass Point. Namn, synlighet och typ kan ändras i vyn Properties (tabb: UML) som visas när du markerar aktuellt attribut. Siffran i hakparentesen visar multiplicitet. 7. Skapa ett paket (geometry) och dra klassen Point dit. 8. Generera java kod. Markera klassen Point, högerklicka och välj Java -> Generate Java Code. Ett nytt javaprojekt skapas med samma namn som rotelementet (geometry) 9. Öppna klassen och titta på koden. Skriv in en JavaDoc-kommentar. 3
10. Skapa en konstruktor i klassen Point med de två attributen via Source -> Generate Constructor -> Using Fields. Kryssa gärna i Omit call to default constructor super(). 11. Generera UML utifrån din klass. Öppna vyn med modellen i vilken du vill infoga klassen. Dra klassen från Project explorer till modellen. Klasser och paket kan dölja varandra så du får själv arrangera det som du vill ha det. Genererade klasser och paket markeras med en pil uppe i högra hörnet. Högerklicka på klassen och utnyttja menyalternativet filter för att välja vilka detaljer som ska visas i diagrammet. 12. Det du får i diagrammet är en ögonblicksbild av klassen Point. För att uppdatera bilden av klassen när du ändrar i koden kan du ändra under tabben Appearance -> Sync with model till true. Ändrar du nu något i koden och efter högerklick på klassen under Project Explorer väljer Java -> Java reverse kommer bilden att uppdateras. Observera att ändrar du i bilden kan du bara generera Java-kod, dvs du kan skapa en ny klass men inte uppdatera en befintlig klass. 13. Lägg till metoden public double distanceto(point other) i Java-editorn och låt den returnera avståndet mellan this och other. Gör en JavaDoc-kommentar för metoden. Uppdatera bilden. 14. Formatera klassen med Source -> Format. 15. Gör en JUnit-test för distanceto via File -> New -> JUnit Test Case. Följ anvisningen att lägga till JUnit-paketet i build path. Implementera metoden test och använd någon assertmetod. Exekvera testet med Run -> Run As -> JUnit Test. 16. Skapa ett nytt paket för tester och flytta testklassen dit. Testa igen. 17. Vi skall nu ändra modellen så att den kan hantera punkter och sträckor antingen i 2 eller 3 dimensioner. Byt namn på Point till Point2D via Refactor -> Rename. 18. Skapa en superklass från Point2D med metoden distanceto via Refactor -> Extract Superclass. Låt superklassen få namnet Point. 19. Ändra signaturen för distanceto med Refactor -> Change Method Signature så att argumentet får typen Point. 20. Uppdatera UML-diagrammet genom att vänsterklicka i diagrammet på den vita ytan (utanför alla klasser etc). Under tabben appearance sätt sync with model till true. Det ska nu visas ett paket generated. Klicka på element i denna och välj sync with model. Fortsätt tills tillräcklig detalj visas. Justera layouten genom att ändra storlek på paket och dra klasser till lämpliga platser. 21. Skapa en klass Point3D med tre koordinater genom att utgå från en kopia av Point2D. 22. Uppdatera UML-diagrammet genom att Java reverse på geometry-paketet. Diagrammet måste vara i fokus och synligt för att detta ska fungera. 23. Skapa en klass (Segment) i UML diagrammet. Segment representerar en sträcka med hjälp av dess ändpunkter. 24. Lägg till operationen length() i Segment i diagrammet 25. Generera java-kod för segment genom att högerklicka på geometry-paketet i diagrammet och välja Java -> generate java code. Du ska nu ha fått ett projekt generated. Ändra i detta i fortsättningen. 26. Ändra i den genererade koden så segment får två punkt-attribut och en konstruktor för dessa och så att metoden length returnerar sträckans längd. Uppdatera UML-diagrammet. Glöm inte att klicka i sync with model för segment-klassen. 27. Testa metoden genom att skapa ett JUnit-test för denna. 4
28. Använd Source Clean Up... på hela paketet. Markera Use custom profile och konfigurera efter egna önskemål, t ex genom att avmarkera Add missing Annotations under fliken Missing Code och markera de fem rutorna under fliken Code Organizing. 29. När uppgiften är färdig bör UML-diagrammet se ut ungefär så här. 5. UMLetino Du ska nu testa ett annat verktyg för att rita UML-diagram. Verktyget är webb-baserat så du surfar in till: http://www.umletino.com och klickar på start-länken Det som skiljer verktyget från papyrus är att det inte finns en koppling till koden som skrivs. Kod implementeras och underhålls separat från UML-diagrammet. Uppgift Rita klassdiagrammet för geometry-paketet i umletino. Spara undan och ladda in diagrammet igen. Exportera diagrammet till en bild. 5