• Keine Ergebnisse gefunden

Unterst¨ utzung durch Cheat Sheets

7.3 Eclipse-Integration

7.3.4 Unterst¨ utzung durch Cheat Sheets

Cheat Sheets sind in Eclipse eine verbreitete und gelungene M¨oglichkeit, den Nutzer sprichw¨ortlich

”an die Hand zu nehmen“. Sie f¨uhren ihn Schritt f¨ur Schritt, anhand ei-nes einfachen Beispiels, durch den gesamten Entwicklungsprozess. Dabei kann das Cheat Sheet den Nutzer nicht nur durch einen Text anleiten, sondern auch das ¨Offnen von

7Eine Erkl¨arung des GMF-Dashboards findet sich unter https://wiki.eclipse.org/Graphical_

Modeling_Framework/Tutorial/Part_4.

Dialogen direkt aus dem Cheat Sheet erm¨oglichen. Bestehende Cheat Sheets f¨uhren den Nutzer beispielsweise in die Plugin-Entwicklung mit Eclipse oder das EMF-Rahmenwerk ein. Selbst das bekannte

”Hello World“-Programm kann in Eclipse mit Hilfe eines Cheat Sheets erstellt werden. So liegt es nahe, auch f¨ur ModGraph eines anzubieten, das - an-hand eines sehr einfachen Beispiels - in die Modellierung mit Graphtransformationsregeln einf¨uhrt, indem es dem Nutzer die wichtigsten Konzepte erkl¨art.

Der Nutzer wird dazu direkt aus der EMF-Welt abgeholt, indem ein sehr bekanntes Beispiel aus dieser, die Bibliothek, wiederverwendet wird. Es wird um zwei Methoden er-weitert. Beide dienen der Akquise einzelner B¨ucher. Dabei ist einmal der Autor bekannt, das andere Mal handelt es sich um einen neuen Autor, der ebenso wie das Buch, im Sys-tem angelegt werden muss. Anhand dieser Beispiele wird ein Einstieg in die Modellierung mit den grundlegenden Elementen einer ModGraph-Regel gegeben.

Das interaktive Cheat Sheet ist in Abbildung 7.14 rechts gezeigt. Es leitet den Nutzer von Anfang an durch den Entwicklungsprozess, indem es im ersten Schritt zur Erzeu-gung eines neuen ModGraph-Projektes anleitet. Innerhalb des Projekts wird zun¨achst das Ecore-Modell der Bibliothek erstellt, aus dem Quelltext generiert wird. Die Erstel-lung des Modells erfolgt Schritt f¨ur Schritt, um auch dem nicht EMF-erfahrenen Benutzer einen Einstieg zu bieten. Es ist in Abbildung 7.14 oben links dargestellt. Darauf aufbau-end wird die ModGraph-Regel modelliert, indem der Nutzer mit einem Rechtsklick auf die gew¨unschte Operation klickt und die Implementierung dieser als ModGraph-Regel w¨ahlt. Der in Abbildung 7.14 unten dargestellte Editor ¨offnet sich. Er wird zun¨achst erkl¨art und beinhaltet anfangs nur die mit GraphPatternbezeichnete Fl¨ache zur Erstel-lung des Graphmusters f¨ur die Regel. Der Editor wird ebenso kleinschrittig bef¨ullt. Jedes Objekt wird im Cheat Sheet mit einer Erkl¨arung seiner Bedeutung und der korrekten Erstellung eingef¨uhrt. Dies ist in Abbildung 7.14 rechts ausschnittsweise f¨ur ein Objekt, einen Link und eine Vorbedingung gezeigt. Die sich ergebende Regel ist in der Abbildung links unten zu sehen.

In einer weiteren Regel, welche die zweite modellierte Operation implementiert, wird der Nutzer in die Verwendung von NACs eingef¨uhrt. Diese Regel modelliert die Akquise eines Buches, dessen Autor nicht bekannt ist. Das entstehende Graphmuster ist dem abgebildeten ¨ahnlich. Der Autor ist jedoch ebenso durch einen zu erzeugenden Knoten modelliert, dem der ¨ubergebene Name zugewiesen wird. Zudem beinhaltet die Regel eine NAC, die verbietet, dass die Bibliothek bereits einen Autor mit diesem Namen kennt.

Neben der Erstellung von Graphtransformationsregeln wird der Nutzer in ihre Vali-dierung und in die Java-Quelltextgenerierung aus einer Regel eingef¨uhrt. Dabei ist der Aufruf der Validierung und der Generierung direkt aus dem Cheat Sheet m¨oglich, um den Nutzer anfangs nicht mit der Suche nach Men¨ueintr¨agen zu belasten.

Das so erzeugte Beispiel soll den Modellierer dazu animieren, selbstst¨andig die weite-ren M¨oglichkeiten zur Nutzung von ModGraph zu erkunden. So kann er beispielsweise mit Hilfe des Dashboards ein Xcore-Modell erstellen. Dieses kann dazu genutzt werden, mittels eines Xcore-Kontrollflusses eine Abfrage zur Steuerung der beiden Regeln zu er-stellen. Alternativ kann auch die Generierung auf Modellebene getestet werden, indem die Regeln selbst in das Xcore-Modell generiert werden.

Abbildung7.14:ImCheatSheet(rechts)undausgearbeitetesBeispiel(links)mitEcore-Klassendiagramm(oben)undderRegelzur ImplementierungderOperationaquireBook(...)(unten)

Teil IV Evaluation

Wenns l¨auft, dann l¨aufts.”

(Sprichwort)

Inhaltsverzeichnis - Teil IV

8 Propagierendes Refactoring 165

8.1 Entstehende Problematik durch abh¨angige Modelle in ModGraph . . . . 166 8.2 Konzeption des propagierenden Refactorings . . . 169 8.3 Implementierung . . . 176 8.3.1 Architektur des propagierenden Refactorings . . . 176 8.3.2 Beispielrefactoring: ¨Andern einer bidirektionalen Referenz in eine

unidirektionale . . . 178 8.3.3 Refactoring 2: Extrahieren einer Klasse . . . 182

9 Integration mit modalen Sequenzdiagrammen 187

9.1 Theoretische ¨Uberlegungen . . . 187 9.1.1 Beschreibung typischer Systeme am Beispiel . . . 187 9.1.2 Modale Sequenzdiagramme und Play-out . . . 190 9.1.3 Integration von MSDs mit Graphtransformationsregeln . . . 194 9.2 Prototypische Werkzeugintegration von ModGraph und ScenarioTools . . 197

10 Diskussion und Abgrenzung des Ansatzes 201

10.1 Diskussion des Ansatzes . . . 201 10.1.1 Evaluation der Regeln . . . 201 10.1.2 Laufzeitmessungen . . . 207 10.2 Abgrenzung des ModGraph-Ansatzes zu verwandten Arbeiten . . . 211 10.2.1 EMF und ModGraph . . . 212 10.2.2 ModGraph und Xcore . . . 213 10.2.3 Modelltransformationswerkzeuge und ModGraph . . . 214 10.3 Abgrenzung des propagierenden Refactorings . . . 219 10.4 Abgrenzung der Integration der Regeln mit MSDs . . . 220 10.5 Ergebnis und Ausblick . . . 222

8 Propagierendes Refactoring

Refactoring ist ein g¨angiger Prozess bei der Entwicklung von Software. Es wird zur Ver-besserung des Designs von Programmen verwendet. Ziel dabei ist, diese ¨ubersichtlicher zu gestalten, indem unn¨otige Teile wegfallen oder redundante zusammengefasst werden, um die Wahrscheinlichkeit des Auftretens von Fehlern zu verringern.

Der Definition von Martin Fowler [33] folgend, handelt es sich beim Refactoring um eine Aktivit¨at Software durch Anwendung einer Reihe von Transformationen zu restruk-turieren ohne deren nach außen hin sichtbares, beobachtbares Verhalten zu ver¨andern.

Die m¨oglichen Transformationen beziehen sich in Fowlers urspr¨unglicher Fassung auf (objektorienterte) Programme. Das hier gemeinte Verhalten bezieht sich auf das End-produkt, das an den Nutzer ausgeliefert wird. F¨ur den Entwickler kann sich das interne Verhalten durch Refactoring deutlich ¨andern - man denke an den einfachen Fall des Hin-zuf¨ugens oder Entfernens eines Parameters zu einer Methode, der eine ¨Anderung aller Methodenaufrufe mit sich bringt.

Betrachtet man das Refactoring vom Standpunkt der modellgetriebenen Softwareent-wicklung, so stellt sich die Frage, inwiefern es auf Modelle angewendet werden kann. F¨ur einzelne strukturelle Modelle ist dieser Vorgang bereits von Biermann [14] und Mens [51, 52] untersucht worden.

Praktisch gesehen sind f¨ur sich allein stehende Modelle nicht immer gegeben. Sobald Verhaltensmodellierung zum Softwaredesign genutzt wird, entstehen Abh¨angigkeiten zwischen Struktur- und Verhaltensmodellen.1 Dies gilt unabh¨angig von der genauen Auspr¨agung der Modelle. Beispielsweise stehen in der UML Aktivit¨ats- und Sequenzdia-gramme in der Designphase immer mit dem zugeh¨origen Klassendiagramm in Verbin-dung, indem sie das Verhalten von aus den Klassen instanziierten Objekten darstellen.

Ebenso sind die hier vorgestellten Graphtransformationsregeln von dem ihnen zugeord-neten Ecore-Modell abh¨angig, indem sie dessen Elemente referenzieren.

Es entstehen Mengen abh¨angiger Modelle, welche konsistent gehalten werden m¨ussen.

Dazu ist die Propagation aller ¨Anderungen innerhalb der - in sich abh¨angigen - Mo-dellmenge notwendig. Wie sich dies gestaltet, h¨angt von der genauen Auspr¨agung der Modellabh¨angigkeiten ab.

Im vorliegenden Kapitel wird daher die Konsistenzerhaltung zwischen Graphtransfor-mationsregeln und deren zugeh¨origem Ecore-Modell bei Anwendung von Refactoring-operationen untersucht. Dazu werden propagierende Refactorings eingef¨uhrt. Sie bie-ten einen - an Fowlers Definition angelehnbie-ten - Katalog von Refactorings auf einem Ecore-Modell und propagieren die dadurch entstandenen ¨Anderungen, sofern n¨otig, an

1Verhaltensmodellierung kann ebenfalls w¨ahrend der Anforderungsanalyse genutzt werden. Hierbei treten noch keine Abh¨angigkeiten auf, da unter Umst¨anden noch kein strukturelles Modell existiert.

EcoreͲ Metamodel

GraphtransformationsͲ Metamodel

M0:Instanzen M1:EcoreͲ

Model instanziiert

instanziiert GraphtransformationsͲ

regel

instanziiert instanziiert

implementiertOperation/

referenziert

testet/transformiert Mengeabhängiger Modelle

Abbildung 8.1: Entstehende Abh¨angigkeiten einer Regel bei M0-Anwendung

die Graphtransformationsregeln. Diese Refactorings sind in [81] und insbesondere in [82] ver¨offentlicht. Die erste Version der Modell-Refactorings wurde im Rahmen einer Bachelor-Arbeit [27] erstellt. Sie wurden sp¨ater erweitert.

Zudem sei an dieser Stelle angemerkt, dass die, unter Umst¨anden vom Nutzer erstell-ten, Xcore-Operationen zur prozeduralen Verhaltensbeschreibung in ModGraph bislang unber¨ucksichtigt bleiben. Sie m¨ussen manuell angepasst werden.

8.1 Entstehende Problematik durch abh¨ angige Modelle in ModGraph

Um die zu l¨osende Problematik hinter den Refactorings zu ergr¨unden, werden die bereits in Kapitel 5 vorkommenden Modelle und deren Zusammenh¨ange weitergehend unter-sucht. Abbildung 8.1 zeigt die M0-Anwendung einer Regel mit allen zugeh¨origen Meta-modellen und Abh¨angigkeiten. Dabei entsteht immer eine Abh¨angigkeit zwischen einer Regel, dem Modell und dessen Instanz. Diese bilden die in Abbildung 8.1 gelb umran-dete Menge abh¨angiger Modelle. Dabei sind insbesondere das Modell und die Regel -durch die vielen in Abschnitt 6.1.1 beschriebenen Referenzen von der Regel zum Modell - stark vernetzt. Zur Erinnerung sei erw¨ahnt, dass jede Regel die Operation, die sie im-plementiert und auf die diese beinhaltende Klasse verweist. Zudem sind die Knoten und Kanten der Regel ¨uber den Elementen des strukturellen Modells typisiert.

Damit liegt es nahe, dass ¨Anderungen am Modell die Regeln beeinflussen und auf diese propagiert werden m¨ussen. Zudem ist eine Propagation der Modell¨anderungen auf die Instanzen notwendig. Dieser Prozess wird Modellmigration genannt und stellt einen evolution¨aren Prozess dar, der die Migration der Instanzen als Reaktion auf Typ¨anderungen anst¨oßt. Er wurde im Kontext der modellgetriebenen Softwareentwick-lung bereits ausf¨uhrlich untersucht. Rose et al. stellen einen Katalog von Operationen zur gekoppelten Evolution von Metamodellen und deren Modellen im COPE-Rahmenwerk

EvolutiondesEcoreͲModells

Abbildung 8.2:Refactoring am Beispiel Bugtracker: Extrahieren einer Oberklasse

vor [63]. Dabei sind die zu l¨osenden Probleme im Wesentlichen dieselben, die bei der Sche-maevolution von Datenbanken auftreten [11]. Zur Ausf¨uhrung von Modellmigrationen wird in Rose et al. die Sprache Epsilon Flock eingef¨uhrt [64]. Hermannsd¨orfer betrachet in [41] die Evolution von Metamodellen und deren Modellen im COPE-Rahmenwerk.

Unter Ber¨ucksichtigung dieser Arbeiten kann die Migration von Instanzen bei Mo-dell¨anderungen vorgenommen werden. Sie wird hier nicht eingehender betrachtet.

Ubrig bleibt somit die Problematik, ob und wie eine ¨¨ Anderung hier ein Refactoring -am Modell zu ¨Anderungen an den Regeln f¨uhrt. Die Antwort h¨angt von der Art der Anderung ab. Dies bedeutet, dass die Propagation f¨¨ ur jedes Refactoring einzeln unter-sucht werden muss. Die Ergebnisse sind im n¨achsten Abschnitt zusammengefasst. Um diesen Sachverhalt n¨aher betrachten zu k¨onnen, wurde in [27] ein Katalog von Refacto-rings f¨ur Ecore-Modelle mit ModGraph implementiert. Teile davon sollen nun beispiel-haft f¨ur den bereits bekannten Bugtracker gezeigt werden. Bei genauerer Betrachtung des Bugtracker-Modells findet man zwei Refactorings, die den Bugtracker positiv ver¨andern k¨onnen: das Extrahieren einer Oberklasse und das Umwandeln einer bidirektionalen Re-ferenz in eine unidirektionale. Zudem soll die Extraktion einer Klasse zur Verwaltung der zahlreichen Namen eines Nutzers betrachtet werden, da es sich hier um ein komplexes Refactoring handelt.

Betrachtet man den in Abbildung 8.2 oben gezeigten Ausschnitt aus dem Bugtracker-Modell, f¨allt auf, dass die Klassen User, Group und Project jeweils ein Attribut name besitzen. Dieses soll nun in eine gemeinsame, hier abstrakte, Oberklasse verschoben werden. Abbildung 8.2 zeigt diesen Vorgang, markiert durch einen gelben Dreifach-Pfeil.

Oben in der Abbildung ist ein Ausschnitt aus dem Modell vor der Refactoringoperation dargestellt und mitCDbeschriftet. Die Klassen tragen jeweils ein gemeinsames Attribut.

Der untere Teil der Abbildung, das Klassendiagramm CD’, zeigt das Modell nach dem

referenziert

transformiert MengeabhängigerModelle

t1:Ticket t2:Ticket t3:Ticket tn:Ticket p1:Project p2:Project pn:Project

EvolutiondesEcoreͲModells Graphtransformationsregel

this t:Ticket

reportedTickets

Abbildung 8.3:Notwendige Anpassungen der Regeln am Beispiel Bugtracker: Umwandeln einer bidirektionalen Referenz in eine unidirektionale

Refactoring. Die gemeinsame Oberklasse NamedElement beinhaltet nun das Attribut name.2

Betrachtet man die Extraktion der Oberklasse hinsichtlich der Propagation auf die Graphtransformationsregeln, so muss zun¨achst gepr¨uft werden, ob ¨Anderungen an die-sen n¨otig sind. Im Klassendiagramm wurde eine Vererbungshierarchie aufgebaut. Dies beeinflusst die, in den Instanzen verf¨ugbaren, Attribute nicht. Da die Knoten in den Re-geln Instanzen repr¨asentieren, sind auch deren Attribute nicht betroffen. Es wird keine Propagation ben¨otigt.

Dieses Refactoring stellt den einfachsten Fall dar. Die meisten Refactorings ziehen jedoch notwendige ¨Anderungen der Regeln nach sich, die bislang manuell vorgenom-men werden m¨ussen, um nicht valide Regeln zu vermeiden. Um diesen Fall auf einer

¨uberschaubaren Anzahl von Seiten zu demonstrieren, wird zun¨achst ein moderat kom-plexes Refactoring herangezogen: Das Umwandeln einer bidirektionalen Referenz in eine unidirektionale. Auch dieses soll am Beispiel des Bugtrackers untersucht werden.

In Abbildung 8.3 ist links oben die Modellevolution des Bugtrackers anhand eines Aus-schnitts aus dem Ecore-Modell dargestellt. Ausgangspunkt ist das mit CD beschriftete Ecore-Modell. Es zeigt die bidirektionale Referenz zwischen einem Projekt und den ihm zugeordneten Tickets. Da es sich um eine Enthaltenseinsbeziehung handelt, muss die R¨uckrichtung nicht explizit navigierbar sein. Dementsprechend wird auf dieser Referenz nun ein Refactoring ausgef¨uhrt, das die bidirektionale Referenz in eine unidirektionale umwandelt (gelber Dreifach-Pfeil). Das Ergebnis ist in der Abbildung mit CD’ bezeich-net. Bez¨uglich des Ecore-Modells ist dies ein g¨ultiges Refactoring. Das Problem entsteht in den Regeln. Enthalten diese Links, welche f¨ur Instanzen der nun gel¨oschten Referenz

2Analog k¨onnte nun auch die Beschreibung (description) der Projekte und Gruppen in eine gemeinsame Oberklasse verschoben werden.

stehen, sind sie nach dem Refactoring nicht mehr valide. Nicht valide Regeln d¨urfen keinesfalls Transformationen auf Instanzen durchf¨uhren. Im Beispiel in Abbildung 8.3 ist die rechts dargestellte und mit GT bezeichnete Regel betroffen. Sie stellt die Im-plementierung der Operation allTicketsWithStatusAndSeverity dar, die alle Tickets eines Projekts mit den vorgegebenen Status und Dringlichkeiten zur¨uckgibt. Der nun nicht mehr valide Link owningProjectist mit einem roten X gekennzeichnet. Der mehrwertige Knoten tickets war vor der Modell¨anderung implizit durch den R¨uckw¨artslink zu errei-chen, der nach dem Refactoring fehlt. Um die Validit¨at der Regel wieder herzustellen, muss sie manuell angepasst werden. Dazu wird der Link vom Nutzer durch einen vor-mals die entgegengesetzte Richtung der Referenz repr¨asentierenden Link ersetzt. F¨ur das Beispiel bedeutet dies, dass der Link owningProject durch reportedTickets ersetzt wird, wie es in GT’ der Fall ist. Damit ist GT’ konsistent mit CD’ und es k¨onnen weitere Transformationen auf Instanzen vorgenommen werden.

Diese Anpassung jeder betroffenen Regel ist f¨ur den Nutzer - gerade bei gr¨oßeren Pro-jekten mit vielen Regeln - eine m¨uhsame Aufgabe. Alle Regeln m¨ussen durchsucht und jede Regel muss einzeln angepasst werden. Dies ist der Ansatzpunkt des propagieren-den Refactorings. Wie im Folgenpropagieren-den gezeigt wird, bietet es neben einem Katalog von Refactorings auch eine Propagation auf alle abh¨angigen Graphtransformationsregeln an.

Damit wird auch der in Abbildung 8.3 rechts abgebildete Schritt automatisiert.