• Keine Ergebnisse gefunden

Refactoring 2: Extrahieren einer Klasse

8.3 Implementierung

8.3.3 Refactoring 2: Extrahieren einer Klasse

Das zweite hier betrachtete Refactoring ist das zur Extraktion einer Klasse. Es bringt einen gr¨oßeren Eingriff in das Modell und auch die Regeln mit sich. Betrachtet man wiederum Fowlers Definition des Refactorings:

”Es gibt eine Klasse, die Arbeit f¨ur zwei verrichtet.“

”Erzeuge eine neue Klasse und verschiebe

die relevanten Felder und Methoden von der alten in die neue Klasse.“

(¨ubersetzt aus [33])

Zus¨atzlich werden laut Fowler die beiden Klassen ¨uber eine Referenz von der alten zur neuen Klasse in Beziehung gesetzt.

Im EMF-Kontext bedeutet dies, dass beim Refactoring des Modells eine Klasse aus einer anderen extrahiert wird und Attribute, Referenzen und Operationen der existieren-den Klasse in die neue verschoben werexistieren-den, sowie dass eine unidirektionale Referenz von der alten zur neuen Klasse erzeugt werden muss. Bei der Propagation werden die Kno-ten, die f¨ur Objekte der Klasse stehen, analysiert. Beinhalten diese verschobene Attribute oder Operationsaufrufe verschobener Operationen, wird ein neuer Knoten erzeugt und diese Elemente werden verschoben. Zudem werden der neue und der alte Knoten ¨uber einen Link, welcher die neue Referenz instanziiert, verbunden. Werden Referenzen von der alten zur neuen Klasse verschoben, m¨ussen auch die zugeh¨origen Links an den neuen Knoten verschoben werden. Dieses propagierende Refactoring hat sowohl prozedurale als auch regelbasierte Anteile.

Die Extraktion der Klasse im Modell erfolgt regelbasiert und ist in Abbildung 8.8 dar-gestellt. Die Regel wird direkt beim Refactoring aufgerufen. Der Nutzer markiert bei Auf-ruf des Refactorings die Klasse sowie die Attribute, Referenzen und Operationen, die aus dieser Klasse extrahiert werden sollen. Sie werden der Regel als Parameter ¨ubergeben.

Die Regel pr¨uft in ihrer Vorbedingung, dass die weiteren Parameter(Klassenname und Referenzname) nicht leer sind.7 Ist dies der Fall, wird das Paket (aPackage) zur Klasse (existingClass) ermittelt und durch die NAC gepr¨uft, ob dieses Paket bereits eine Klas-se des vorgegebenen Namens f¨ur die zu extrahierende Klasse enth¨alt (analog f¨ur den Referenznamen). Ist dies nicht der Fall, wird die neue Klasse (newClass), sowie eine neue Referenz (newReference) zwischen der existierenden und der neuen Klasse, erzeugt.

Die zuvor vom Nutzer angegebenen Attribute und Referenzen (hier zu structuralFea-turesToMove zusammengefasst), sowie die Operationen (operationsToMove) werden nun verschoben. Damit ist das Refactoring auf dem Modell abgeschlossen.

Die Propagation zeigt sich deutlich komplexer. Auflistung 8.3 zeigt einen interessan-ten Ausschnitt. Hier werden zun¨achst die Regeln ermittelt, deren Graphmuster Knoten enthalten, die auf die ver¨anderte Klasse zeigen (Zeilen 13-22). Diese Knoten werden in den folgenden Zeilen (23-60) untersucht und Elemente, die auf verschobene Attribu-te, Felder und Operationen zeigen, ermittelt. In den Zeilen 62 und 63 wird die Regel

7are eine leere Zeichenkette zugelassen, br¨auchte man keine Vorbedingung, die null-Pr¨ufung erfolgt ahrend der Mustersuche.

Abbildung8.8:ModGraph-RegelzumExtrahiereneinerKlasse

Abbildung 8.9: ModGraph-Regel zur Propagation der strukturellen Anteile des Refactorings Ex-trahieren einer Klasse

zur Transformation der strukturellen Eigenschaften aufgerufen. Sie ist in Abbildung 8.9 dargestellt. Allerdings geschieht dies nur, wenn Elemente der Regel bearbeitet werden m¨ussen, wie die Bedingung direkt dar¨uber zeigt (Zeilen 60 & 61). Danach werden alle anderen textuellen Felder der Regel betrachtet. Dies ist im Wesentlichen durch Parsen von Zeichenketten realisiert und daher nicht abgebildet. Zudem wird ein grafisches Up-date der Regel ausgef¨uhrt, so dass nicht nur der Baumeditor, sondern auch die grafische Darstellung, das GMF-basierte Diagramm, den neuen Zustand der Regel anzeigt.

Die Regel zur Propagation der ¨Anderungen an den Links und Attributen im Graph-muster ist in Abbildung 8.9 dargestellt. Hier werden die Regel (rule), die existierende Klasse (existingClass), die neu extrahierte Klasse (extractedClass), der betroffene Knoten (node) und alle zu verschiebenden Attribute (gTAttributes), Felder (gTFields) und Links

¨

ubergeben. Die Links werden dabei in eingehende (gTInLinks) und ausgehende (gTOut-Links) Links des Knotens unterschieden.

In der Regel wird ein neuer, einwertiger, ungebundener Knoten erzeugt (newNode), der den Status des ¨ubergebenen, betroffenen Knotens zugewiesen bekommt. Ihm wer-den ¨ubergebene Felder, Links und Attribute zugewiesen. Es handelt sich hier um die Zuweisung eines neuen Containers f¨ur die Felder, Links und Attribute. Sie werden damit automatisch aus dem Knoten nodeentfernt (Exklusivit¨at). Des Weiteren wird ein neuer Link (newLink) erzeugt, der eine Instanz der neu erzeugten Referenz im Modell darstellt.

BeispielmengeabhängigerModelleNACHdemRefactoring BeispielmengeabhängigerModelle

VORdemRefactoring

Abbildung 8.10:Anwendung des propagierenden Refactorings auf das Bugtracker Beispiel: Ex-traktion der Klasse Names zur Verwaltung der Namen des Nutzers

Er verbindet die beiden betrachteten Knoten und erh¨alt den selben Status wie diese. Die Regel zur Propagation der ¨Anderungen in die NAC ist analog aufgebaut. Als Parameter wird hier wiederum die NAC statt der Regel angegeben.

Betrachtet man nun die Ergebnisse des Refactorings in Abbildung 8.10, wurde das Refactoring korrekt ausgef¨uhrt. Oben in der Abbildung ist die Klasse User mit allen At-tributen gezeigt, sowie das Graphmuster der Regel zur Implementierung der Operation createUser der Klasse BugTracker. Aus der Klasse User werden die zahlreichen Namen extrahiert. Sie werden in die Klasse Namesverschoben, die diese im Weiteren verwaltet.

Die Klasse User greift auf sie durch die Referenz names zu. Der Zustand des Modells nach dem Refactoring ist in Abbildung 8.10 unten dargestellt. Die Regel wird gem¨aß der eben beschriebenen Propagation ver¨andert. Ein Link und ein Objekt kommen hinzu.

Diese sind ¨uber der neuen Referenz bzw. der extrahierten Klasse typisiert. Der Propa-gationsregel folgend, wird der neue Knoten mit newNode benannt. Ihm wird, ebenso wieUser, der Status zu erzeugen zugeordnet. Die ver¨anderte Regel nach Anwendung der Propagation ist in der Abbildung unten dargestellt. Sie ist wieder konsistent zum Modell und das propagierende Refactoring ist abgeschlossen.