Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Refactoring Java Code

Ähnliche Präsentationen


Präsentation zum Thema: "Refactoring Java Code"—  Präsentation transkript:

1 Refactoring Java Code

2 2 Übersicht Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung

3 3 Refactoring, Martin Fowler Dieses Tutorial beruht im Wesentlichen auf dem Buch Refactoring – Improving the Design of Existing Code von Martin Fowler. Standardwerk Abweichungen im Detail Dieses Tutorial beruht im Wesentlichen auf dem Buch Refactoring – Improving the Design of Existing Code von Martin Fowler. Standardwerk Abweichungen im Detail

4 4 Refactoring: Definition Refactoring ist die Verbesserung der Qualität von vorhandenem Quell- text ohne Veränderung der Funktionalität.

5 5 Problem Das Design eines Systems neigt dazu, im Laufe der Zeit immer schlechter zu werden. Neue Funktionalität wird gefordert, alte entfällt Vorhandene Anforderungen werden geändert Das Verständnis des Systems ändert sich Das Design eines Systems neigt dazu, im Laufe der Zeit immer schlechter zu werden. Neue Funktionalität wird gefordert, alte entfällt Vorhandene Anforderungen werden geändert Das Verständnis des Systems ändert sich

6 6 Refactoring als Gegenmittel Um dem entgegenzuwirken, muss das Design mit dem System wachsen. Kleine Schritte reduzieren das Risiko Trennung zwischen Refactoring und Erweiterung des Systems hilft zu fokussieren Arbeit am System stößt auf sich ändernde Teile Um dem entgegenzuwirken, muss das Design mit dem System wachsen. Kleine Schritte reduzieren das Risiko Trennung zwischen Refactoring und Erweiterung des Systems hilft zu fokussieren Arbeit am System stößt auf sich ändernde Teile

7 7 Demonstration Ein Quelltext sagt mehr als tausend Folien... Der Quelltext ist im Internet verfügbar: Ein Quelltext sagt mehr als tausend Folien... Der Quelltext ist im Internet verfügbar:

8 8 Was ist geschehen? Ein Stück Software wurde überarbeitet, ohne dass sich sein Verhalten geändert hat. Auslöser: eine anstehende Änderung Code war unnötig kompliziert Änderungen in kleinen Schritten Ein Stück Software wurde überarbeitet, ohne dass sich sein Verhalten geändert hat. Auslöser: eine anstehende Änderung Code war unnötig kompliziert Änderungen in kleinen Schritten

9 9 Wann Refactoring Der richtige Zeitpunkt für Refactoring ist, wenn man sich ohnehin mit dem Quelltext beschäftigt. Beim Debugging Beim Erweitern/Ändern Wenn ein Kollege mit einer Frage kommt Der richtige Zeitpunkt für Refactoring ist, wenn man sich ohnehin mit dem Quelltext beschäftigt. Beim Debugging Beim Erweitern/Ändern Wenn ein Kollege mit einer Frage kommt

10 10 Kleine Schritte Refactoring funktioniert am besten, wenn man es in kleinen Schritten tut. Schutz vor Flüchtigkeitsfehlern Man behält den Überblick Bei Problem: einfach einen Schritt zurück Refactoring funktioniert am besten, wenn man es in kleinen Schritten tut. Schutz vor Flüchtigkeitsfehlern Man behält den Überblick Bei Problem: einfach einen Schritt zurück

11 11 Die beiden Hüte Refactoring und Erweiterung des Systems wechseln sich ab. Saubere Trennung für besseren Überblick Zettel und Stift als Gedächtnisstütze Man hat entweder den Refactoring-Hut oder den Erweiterungs-Hut auf Refactoring und Erweiterung des Systems wechseln sich ab. Saubere Trennung für besseren Überblick Zettel und Stift als Gedächtnisstütze Man hat entweder den Refactoring-Hut oder den Erweiterungs-Hut auf

12 12 Zusammenfassung Refactoring erlaubt es, nachträglich Designentscheidungen zu ändern. Zeitpunkt: wenn man ohnehin mit dem Code zu tun hat Kleine Schritte: Entspannt bleiben, bei Problem einen Schritt zurück. Refactoring erlaubt es, nachträglich Designentscheidungen zu ändern. Zeitpunkt: wenn man ohnehin mit dem Code zu tun hat Kleine Schritte: Entspannt bleiben, bei Problem einen Schritt zurück.

13 13 Übersicht Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung

14 14 Altersschwäche Software kann an Altersschwäche sterben. Design wächst nicht mit den Anforderungen Wartung als Albtraum Manchmal schon vor Inbetriebnahme... Software kann an Altersschwäche sterben. Design wächst nicht mit den Anforderungen Wartung als Albtraum Manchmal schon vor Inbetriebnahme...

15 15 Hellseherei Fixiertes Design vorab ist problematisch. Anforderungen ändern sich Das Verständnis wächst Hellseherei funktioniert oft nicht Ausnahme: feste Anforderungen, erfahrenes Team (z.B. reine Migration) Fixiertes Design vorab ist problematisch. Anforderungen ändern sich Das Verständnis wächst Hellseherei funktioniert oft nicht Ausnahme: feste Anforderungen, erfahrenes Team (z.B. reine Migration)

16 16 Traditionelles Vorgehen Das Wasserfall-Modell ist immer noch sehr verbreitet. Änderungen werden mit der Zeit teurer Risiko minimieren Das Wasserfall-Modell ist immer noch sehr verbreitet. Änderungen werden mit der Zeit teurer Risiko minimieren

17 17 Änderungen billig machen Agile Vorgehensmodelle unterstützen späte Änderungen Z.B. eXtreme Programming Weniger Gewicht auf Planung am Anfang System profitiert von wachsender Erfahrung Agile Vorgehensmodelle unterstützen späte Änderungen Z.B. eXtreme Programming Weniger Gewicht auf Planung am Anfang System profitiert von wachsender Erfahrung

18 18 Kriterien für das Vorgehensmodell Refactoring funktioniert am besten in einem Vorgehensmodell, bei dem Änderungen billig und sicher sind. Dann kann das System von der wachsenden Erfahrung profitieren. Refactoring funktioniert am besten in einem Vorgehensmodell, bei dem Änderungen billig und sicher sind. Dann kann das System von der wachsenden Erfahrung profitieren.

19 19 Source-Code enthält das Design Refactoring ändert das Design schrittweise im Quelltext. Sonstige Design- Dokumentation bremst dabei. Keine Hackerei: Anforderung an den Code Je feiner die übrige Designdokumentation ist, desto problematischer Design Freeze schließt Refactoring aus Refactoring ändert das Design schrittweise im Quelltext. Sonstige Design- Dokumentation bremst dabei. Keine Hackerei: Anforderung an den Code Je feiner die übrige Designdokumentation ist, desto problematischer Design Freeze schließt Refactoring aus

20 20 Einfachheit als Wert Softwareentwicklung ist eine der kompliziertesten Tätigkeiten der Welt. Quelltexte sind primär für menschliche Leser Möglichst viele Hilfestellungen Unnötige Komplexität entfernen Softwareentwicklung ist eine der kompliziertesten Tätigkeiten der Welt. Quelltexte sind primär für menschliche Leser Möglichst viele Hilfestellungen Unnötige Komplexität entfernen

21 21 Wenn du es siehst, tue es Ein Problem lieber gleich angehen als es auf die lange Bank schieben. Probleme verschwinden nicht von alleine Vorgehensmodell muss das zulassen Mut als Wert Ausnahme: kurz vor einer Deadline. Ein Problem lieber gleich angehen als es auf die lange Bank schieben. Probleme verschwinden nicht von alleine Vorgehensmodell muss das zulassen Mut als Wert Ausnahme: kurz vor einer Deadline.

22 22 Qualität als Wert? Qualität als Wert entwickelt leicht eine Eigendynamik. Qualität ist relativ zu Maßstäben; damit lässt sich Vieles begründen Stattdessen klarer Einfachheit und Kommunikation Qualität als Wert entwickelt leicht eine Eigendynamik. Qualität ist relativ zu Maßstäben; damit lässt sich Vieles begründen Stattdessen klarer Einfachheit und Kommunikation

23 23 Versionsverwaltung Eine Versionsverwaltung ist eine wichtige Voraussetzung für Refactoring, besonders im Team. Reversibilität von Refactorings Kurze Check-In-Zyklen Eine Versionsverwaltung ist eine wichtige Voraussetzung für Refactoring, besonders im Team. Reversibilität von Refactorings Kurze Check-In-Zyklen

24 24 Buildprozess Nur ein wohldefinierter Buildprozess erlaubt die Überprüfung von Änderungen. An jedem Arbeitsplatz verfügbar Muss gelebt werden Integration in IDE Früh aufsetzen und mit dem Projekt wachsen lassen Nur ein wohldefinierter Buildprozess erlaubt die Überprüfung von Änderungen. An jedem Arbeitsplatz verfügbar Muss gelebt werden Integration in IDE Früh aufsetzen und mit dem Projekt wachsen lassen

25 25 Häufige Integration Es muss immer ein funktionstüchtiger Stand des Systems verfügbar sein. Systemteile früh aneinanderschrauben, damit sie nicht auseinanderlaufen z.B. nächtlicher Build Es muss immer ein funktionstüchtiger Stand des Systems verfügbar sein. Systemteile früh aneinanderschrauben, damit sie nicht auseinanderlaufen z.B. nächtlicher Build

26 26 Einwände gegen Refactoring Es gibt – teilweise tatsächliche – Hindernisse: Design ist nicht mehr dokumentiert. Refactoring lohnt sich nicht. Wo sind die kurzfristigen Vorteile? Es könnte etwas kaputtgehen. Es gibt – teilweise tatsächliche – Hindernisse: Design ist nicht mehr dokumentiert. Refactoring lohnt sich nicht. Wo sind die kurzfristigen Vorteile? Es könnte etwas kaputtgehen.

27 27 Design ist nicht dokumentiert Einwand: Durch Refactoring laufen Implementierung und Designdokumentation auseinander Im sehr großen Maßstab berechtigter Einwand Ansonsten: Gesonderte Designdokumentation veraltet ohnehin Quelltext gewinnt an Klarheit: Design wird im Quelltext expliziter Einwand: Durch Refactoring laufen Implementierung und Designdokumentation auseinander Im sehr großen Maßstab berechtigter Einwand Ansonsten: Gesonderte Designdokumentation veraltet ohnehin Quelltext gewinnt an Klarheit: Design wird im Quelltext expliziter

28 28 Refactoring lohnt sich nicht Einwand: Während des Refactorings implementiert man keine Funktionalität. Durch Refactoring gleichbleibend gutes Design System bleibt änderbar Nicht ästhetische Selbstbefriedigung Einwand: Während des Refactorings implementiert man keine Funktionalität. Durch Refactoring gleichbleibend gutes Design System bleibt änderbar Nicht ästhetische Selbstbefriedigung

29 29 Keine kurzfristigen Vorteile Einwand: Refactoring bringt langfristig Vorteile, aber nicht kurzfristig. Refactoring als Teil des jeweiligen Arbeitspakets Kein Hauruck-Redesign, sondern hier ein wenig und dort ein wenig. Vereinfacht die tägliche Arbeit und spart dabei Zeit. Einwand: Refactoring bringt langfristig Vorteile, aber nicht kurzfristig. Refactoring als Teil des jeweiligen Arbeitspakets Kein Hauruck-Redesign, sondern hier ein wenig und dort ein wenig. Vereinfacht die tägliche Arbeit und spart dabei Zeit.

30 30 Es könnte etwas kaputt gehen Einwand: Refactoring könnte bestehende Funktionalität kaputt machen. JUnit-Tests In kleinen Schritten vorgehen Bei Unsicherheit lieber vorsichtig sein Andererseits: bei jeder Änderung kann etwas kaputtgehen... Einwand: Refactoring könnte bestehende Funktionalität kaputt machen. JUnit-Tests In kleinen Schritten vorgehen Bei Unsicherheit lieber vorsichtig sein Andererseits: bei jeder Änderung kann etwas kaputtgehen...

31 31 Alternative: Einfach tun Wenn das Management nicht von Refactoring überzeugt ist, gibt es die Möglichkeit, es einfach zu tun Der offizielle Weg ist besser Professionelle Verantwortung Es spart Zeit, wird sich also bewähren Wenn das Management nicht von Refactoring überzeugt ist, gibt es die Möglichkeit, es einfach zu tun Der offizielle Weg ist besser Professionelle Verantwortung Es spart Zeit, wird sich also bewähren

32 32 Grenzen des Refactoring Es gibt Situationen, wo Refactoring nicht gut funktioniert. Relationale Datenbanken Fixierte Schnittstellen Hoffnungslos kaputtes System Es gibt Situationen, wo Refactoring nicht gut funktioniert. Relationale Datenbanken Fixierte Schnittstellen Hoffnungslos kaputtes System

33 33 Zusammenfassung Das Umfeld des Refactoring: Agile Prozesse erlauben es, spät Änderungen am System durchzuführen Versionsverwaltung, Build Management Es gibt Einwände, mit denen man sich auseinander setzen muss Refactoring ist lernbar: Keine Scheu! Das Umfeld des Refactoring: Agile Prozesse erlauben es, spät Änderungen am System durchzuführen Versionsverwaltung, Build Management Es gibt Einwände, mit denen man sich auseinander setzen muss Refactoring ist lernbar: Keine Scheu!

34 34 Übersicht Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung

35 35 Wann Refactoring? Das wie ist relativ einfach, aber wann und wo soll man refaktorieren? Lohnt sich ein bestimmtes Refactoring? In welche Richtung soll man gehen? Wo fängt man an? Wann soll man aufhören? Das wie ist relativ einfach, aber wann und wo soll man refaktorieren? Lohnt sich ein bestimmtes Refactoring? In welche Richtung soll man gehen? Wo fängt man an? Wann soll man aufhören?

36 36 Code Smells Geruch von Quelltexten ist eine Metapher, um über ihre Qualität zu reden. Katalog von Gerüchen Keine präzisen Kriterien Hilfestellung für die Intuition Geruch von Quelltexten ist eine Metapher, um über ihre Qualität zu reden. Katalog von Gerüchen Keine präzisen Kriterien Hilfestellung für die Intuition

37 37 Duplizierter Code Wenn das Gleiche an zwei Stellen im Quelltext steht, stinkt das zum Himmel. Der Quelltext ist unübersichtlich Das System ist schwer zu ändern Inkonsistenzen und damit Fehler schleichen sich ein Wenn das Gleiche an zwei Stellen im Quelltext steht, stinkt das zum Himmel. Der Quelltext ist unübersichtlich Das System ist schwer zu ändern Inkonsistenzen und damit Fehler schleichen sich ein

38 38 Datenklasse Eine Klasse, die nur Daten und keine Logik enthält, ist ein Indiz für Verbesserungs- potential Oft gibt es Funktionalität, die im Wesentlichen auf diesen Daten operiert Andernfalls ist vielleicht die Klasse schlecht geschnitten Eine Klasse, die nur Daten und keine Logik enthält, ist ein Indiz für Verbesserungs- potential Oft gibt es Funktionalität, die im Wesentlichen auf diesen Daten operiert Andernfalls ist vielleicht die Klasse schlecht geschnitten

39 39 Kommentare Kommentare an sich riechen gut, sie werden aber oft als Deodorant verwendet. Kommentare sind Zeichen, dass der Quelltext selbst nicht klar verständlich ist Kommentare können veralten oder in die Irre führen Kommentare an sich riechen gut, sie werden aber oft als Deodorant verwendet. Kommentare sind Zeichen, dass der Quelltext selbst nicht klar verständlich ist Kommentare können veralten oder in die Irre führen

40 40 Unangebrachte Intimität Zwei Klassen, die ausgiebig gegenseitig Methoden aufrufen, sind oft nicht gut geschnitten. Sie sind eng gekoppelt und schwierig unabhängig voneinander zu ändern Sie sind schwierig zu benutzen, weil sie keine klare Aufgabenteilung haben Zwei Klassen, die ausgiebig gegenseitig Methoden aufrufen, sind oft nicht gut geschnitten. Sie sind eng gekoppelt und schwierig unabhängig voneinander zu ändern Sie sind schwierig zu benutzen, weil sie keine klare Aufgabenteilung haben

41 41 Neid Eine Methode, die im Wesentlichen auf Attributen einer anderen Klasse operiert, ist dort wahrscheinlich besser aufgehoben. Die Signatur der Methode wird dann einfacher und die Aufgabenteilung der Klassen natürlicher Eine Methode, die im Wesentlichen auf Attributen einer anderen Klasse operiert, ist dort wahrscheinlich besser aufgehoben. Die Signatur der Methode wird dann einfacher und die Aufgabenteilung der Klassen natürlicher

42 42 Switch Fallunterscheidungen mit switch führen oft zu doppeltem Code, weil die gleichen Fälle mehrmals unterschieden werden. Switch ist nicht typsicher Man vergisst leicht Fälle Zusätzliche Fälle müssen an vielen Stellen bedacht werden Fallunterscheidungen mit switch führen oft zu doppeltem Code, weil die gleichen Fälle mehrmals unterschieden werden. Switch ist nicht typsicher Man vergisst leicht Fälle Zusätzliche Fälle müssen an vielen Stellen bedacht werden

43 43 Lange Methode Lange Methoden sind aufwendiger zu verstehen als kurze. Kurze Methoden können durch ihre Namen den Quelltext dokumentieren Durch Extrahieren kurzer Methoden kann man Code-Duplizierung vermeiden und Aufgaben zwischen Klassen verschieben Lange Methoden sind aufwendiger zu verstehen als kurze. Kurze Methoden können durch ihre Namen den Quelltext dokumentieren Durch Extrahieren kurzer Methoden kann man Code-Duplizierung vermeiden und Aufgaben zwischen Klassen verschieben

44 44 Monster-Klasse Eine zu große Klasse wird unübersichtlich. Zu viele Attribute führen leicht zu Code- Duplizierung Eine zu große Klasse wird unübersichtlich. Zu viele Attribute führen leicht zu Code- Duplizierung

45 45 Datenklumpen Eine Gruppe von Daten, die oft zusammen vorkommt, kann man oft als Klasse zusammenfassen. Dieser Typ kann Funktionalität bekommen und dadurch doppelten Code vermeiden Die Verwendung der Daten wird einfacher Eine Gruppe von Daten, die oft zusammen vorkommt, kann man oft als Klasse zusammenfassen. Dieser Typ kann Funktionalität bekommen und dadurch doppelten Code vermeiden Die Verwendung der Daten wird einfacher + 5$

46 46 Unechte Primitive Datentypen Primitive Datentypen können oft besser durch Klassen ersetzt werden. Eigene Werttypen sind typsicher und dokumentieren den Code Manchmal gibt es falsche Scheu vor kleinen Klassen Primitive Datentypen können oft besser durch Klassen ersetzt werden. Eigene Werttypen sind typsicher und dokumentieren den Code Manchmal gibt es falsche Scheu vor kleinen Klassen 5$

47 47 Schrotkugeln herausoperieren Wenn man viele Klassen ändern muss, um einen Aspekt zu ändern, ließe er sich vielleicht an einer Stelle lokalisieren. Man übersieht sonst leicht eine Stelle Es entsteht leicht doppelter Code Wenn man viele Klassen ändern muss, um einen Aspekt zu ändern, ließe er sich vielleicht an einer Stelle lokalisieren. Man übersieht sonst leicht eine Stelle Es entsteht leicht doppelter Code

48 48 Kombinierte Abstraktionen Wenn eine Klasse von vielen verschiedenen Änderungen betroffen wird, ist es vielleicht besser, sie zu spalten. Sonst betreffen Änderungen potentiell mehr Quelltext als nötig Aufteilung macht den Code übersichtlicher Wenn eine Klasse von vielen verschiedenen Änderungen betroffen wird, ist es vielleicht besser, sie zu spalten. Sonst betreffen Änderungen potentiell mehr Quelltext als nötig Aufteilung macht den Code übersichtlicher

49 49 Lange Parameterliste Eine lange Parameterliste deutet auf Verbesserungspotential hin. Lange Parameterlisten sind unübersichtlich Sie neigen dazu, sich zu ändern Attribute oder Parameterobjekte sind besser Eine lange Parameterliste deutet auf Verbesserungspotential hin. Lange Parameterlisten sind unübersichtlich Sie neigen dazu, sich zu ändern Attribute oder Parameterobjekte sind besser

50 50 Faule Klasse Eine Klasse, die fast nichts mehr tut, kann mehr im Weg sein als nützen. Jede Klasse bedeutet Komplexität Der Nutzen kann kleiner werden als der Preis Eine Klasse, die fast nichts mehr tut, kann mehr im Weg sein als nützen. Jede Klasse bedeutet Komplexität Der Nutzen kann kleiner werden als der Preis

51 51 Hellseherei Oft berücksichtigen Leute sicherheitshalber Erweiterungen, die eventuell später benötigt werden. Das Design wird komplizierter, schwieriger zu verstehen und ändern Indiz: Eine Methode oder Klasse wird nur von Tests verwendet Oft berücksichtigen Leute sicherheitshalber Erweiterungen, die eventuell später benötigt werden. Das Design wird komplizierter, schwieriger zu verstehen und ändern Indiz: Eine Methode oder Klasse wird nur von Tests verwendet

52 52 Methodenketten Wenn man erst eine Reihe von get- Methoden aufrufen muss, um das eigentlich interessante Objekt zu bekommen, durchbricht das die Kapselung. Änderungen der dazwischenliegenden Klassen betreffen den Client Wenn man erst eine Reihe von get- Methoden aufrufen muss, um das eigentlich interessante Objekt zu bekommen, durchbricht das die Kapselung. Änderungen der dazwischenliegenden Klassen betreffen den Client

53 53 Vermittler Wenn viele Methoden einer Klasse den Aufruf einfach nur durchreichen, macht das das Interface unnötig kompliziert. Der Client sollte stattdessen direkt mit dem inneren Objekt reden Wenn viele Methoden einer Klasse den Aufruf einfach nur durchreichen, macht das das Interface unnötig kompliziert. Der Client sollte stattdessen direkt mit dem inneren Objekt reden

54 54 Alternative Klassen mit verschiedenen Schnittstellen Wenn mehrere Klassen das Gleiche tun, bedeutet das Code-Duplizierung mit allen ihren Problemen. Das gilt insbesondere bei unterschiedlichen Interfaces Wenn mehrere Klassen das Gleiche tun, bedeutet das Code-Duplizierung mit allen ihren Problemen. Das gilt insbesondere bei unterschiedlichen Interfaces

55 55 Ausgeschlagenes Erbe Wenn eine Unterklasse wesentliche Teile der Basisklasse ignoriert, irritiert das menschliche Leser. Wenn Implementierung ignoriert wird, ist das nicht so schlimm Wenn Teile der Schnittstelle nicht unterstützt werden, ist die Vererbung falsch Wenn eine Unterklasse wesentliche Teile der Basisklasse ignoriert, irritiert das menschliche Leser. Wenn Implementierung ignoriert wird, ist das nicht so schlimm Wenn Teile der Schnittstelle nicht unterstützt werden, ist die Vererbung falsch

56 56 Übersicht Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung

57 57 Automatisierte Modultests Automatisierte Modultests reduzieren das Risiko beim Refactoring. automatisiert: Die Tests laufen auf Knopfdruck ab und brauchen keine Nutzeraktion. Modultests: Getestet werden die einzelnen Klassen. Automatisierte Modultests reduzieren das Risiko beim Refactoring. automatisiert: Die Tests laufen auf Knopfdruck ab und brauchen keine Nutzeraktion. Modultests: Getestet werden die einzelnen Klassen.

58 58 JUnit JUnit ist ein Framework zur Unterstützung von automatisierten Modultests. Tests sind Java-Klassen Test-Schreiben ist kein großer Overhead JUnit ist ein Framework zur Unterstützung von automatisierten Modultests. Tests sind Java-Klassen Test-Schreiben ist kein großer Overhead

59 59 Beispiel Ein dummes aber einfaches Beispiel... Der Quelltext ist im Internet verfügbar: Ein dummes aber einfaches Beispiel... Der Quelltext ist im Internet verfügbar:

60 60 Integration in IDE Der Aufruf von JUnit ist einfach. junit.jar in den ClassPath junit.swingui.TestRunner als Main-Klasse Den Namen des Testfalls als Kommandozeilenparameter Der Aufruf von JUnit ist einfach. junit.jar in den ClassPath junit.swingui.TestRunner als Main-Klasse Den Namen des Testfalls als Kommandozeilenparameter

61 61 Eine Testklasse je Klasse Typischerweise schreibt man zu jeder Klasse eine Testklasse. Testklasse erbt von junit.framework.TestCase Per Namenskonvention endet der Name der Testklasse mit Test Typischerweise schreibt man zu jeder Klasse eine Testklasse. Testklasse erbt von junit.framework.TestCase Per Namenskonvention endet der Name der Testklasse mit Test TestCase BriefmarkeTestBriefmarke

62 62 Tests Zu einer Test-Klasse gehören mehrere Test- Methoden. Namenskonvention: public void test... () Die Reihenfolge der Ausführung steht nicht fest Die Testmethoden müssen unabhängig voneinander sein Zu einer Test-Klasse gehören mehrere Test- Methoden. Namenskonvention: public void test... () Die Reihenfolge der Ausführung steht nicht fest Die Testmethoden müssen unabhängig voneinander sein

63 63 Assertions Die eigentlichen Tests erfolgen als Aufrufe der assert...-Methoden von TestCase. Wenn die Bedingung erfüllt ist, passiert nichts Wenn die Bedingung nicht erfüllt ist, wird dieser Test abgebrochen und als fehl- geschlagen vorgemerkt Die eigentlichen Tests erfolgen als Aufrufe der assert...-Methoden von TestCase. Wenn die Bedingung erfüllt ist, passiert nichts Wenn die Bedingung nicht erfüllt ist, wird dieser Test abgebrochen und als fehl- geschlagen vorgemerkt

64 64 TestSuite Mehrere Tests können als TestSuite zusammengefasst werden. Klasse junit.framework.TestSuite Eine TestSuite kann TestCases und TestSuites enthalten Mehrere Tests können als TestSuite zusammengefasst werden. Klasse junit.framework.TestSuite Eine TestSuite kann TestCases und TestSuites enthalten Test TestCaseTestSuite 1..*

65 65 Beispiel (2) Eine zweite Klasse mit Tests kommt dazu. Der Quelltext ist im Internet verfügbar: Eine zweite Klasse mit Tests kommt dazu. Der Quelltext ist im Internet verfügbar:

66 66 Test vor Implementierung Man kann den Test schon beim Nachdenken über die geplante Funktionalität schreiben. Kleine Schritte: Ein wenig Testen, ein wenig Implementieren usw. Wenn der Test erfolgreich durchläuft, ist man fertig Man kann den Test schon beim Nachdenken über die geplante Funktionalität schreiben. Kleine Schritte: Ein wenig Testen, ein wenig Implementieren usw. Wenn der Test erfolgreich durchläuft, ist man fertig

67 67 Erst fehlschlagen lassen Das Ausprobieren des Tests vor der Implementierung gibt Sicherheit. Vielleicht klappt er ja schon... Man stellt sicher, dass er tatsächlich ausgeführt wird Das Ausprobieren des Tests vor der Implementierung gibt Sicherheit. Vielleicht klappt er ja schon... Man stellt sicher, dass er tatsächlich ausgeführt wird

68 68 Tests als Dokumentation Die Tests dokumentieren die getesteten Klassen genau. Sie zeigen die nötige Initialisierung Sie enthalten ein Beispiel für jede Methode Die Dokumentation ist nie veraltet Die Tests dokumentieren die getesteten Klassen genau. Sie zeigen die nötige Initialisierung Sie enthalten ein Beispiel für jede Methode Die Dokumentation ist nie veraltet

69 69 Beispiel (3) Das Beispiel wird noch einmal erweitert. Der Quelltext ist im Internet verfügbar: Das Beispiel wird noch einmal erweitert. Der Quelltext ist im Internet verfügbar:

70 70 Tests als Sicherheitsnetz Gute Tests schützen davor, unbeabsichtigt Funktionalität zu ändern, auf die sich andere Klassen verlassen. Das ist eine Voraussetzung für zuversichtliches Refactoring Es hilft auch bei Erweiterungen und Änderungen Gute Tests schützen davor, unbeabsichtigt Funktionalität zu ändern, auf die sich andere Klassen verlassen. Das ist eine Voraussetzung für zuversichtliches Refactoring Es hilft auch bei Erweiterungen und Änderungen

71 71 Wie fängt man an? Tests Schreiben braucht Übung, aber… der Einstieg ist leicht eine unvollständige Test-Suite ist hilfreich und kann organisch wachsen durch Refactoring kann man später die Tests verbessern Testen macht Spaß Tests Schreiben braucht Übung, aber… der Einstieg ist leicht eine unvollständige Test-Suite ist hilfreich und kann organisch wachsen durch Refactoring kann man später die Tests verbessern Testen macht Spaß

72 72 Zusammenfassung Refactoring Das Umfeld von Refactoring Code Smells JUnit Refactoring Das Umfeld von Refactoring Code Smells JUnit

73 73 Übersicht Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung

74 74 Katalog Der Katalog ist Hilfestellung. Ziel ist besserer Geruch: Eigenes Urteil! Probieren und Fehler sind ungefährlich: JUnit-Tests Man kann alles rückgängig machen Einstieg: Problem Konkrete Schritte: damit man nichts vergisst Am Ende: Immer compilieren und testen Der Katalog ist Hilfestellung. Ziel ist besserer Geruch: Eigenes Urteil! Probieren und Fehler sind ungefährlich: JUnit-Tests Man kann alles rückgängig machen Einstieg: Problem Konkrete Schritte: damit man nichts vergisst Am Ende: Immer compilieren und testen

75 75 Change Inconsistent Layout Quelltext ist inkonsistent formatiert, insbesondere eingerückt. Layout an Quelltextrichtlinien anpassen Möglichst toolgestützt NICHT den eigenen Geschmack aufzwingen! Quelltext ist inkonsistent formatiert, insbesondere eingerückt. Layout an Quelltextrichtlinien anpassen Möglichst toolgestützt NICHT den eigenen Geschmack aufzwingen!

76 76 Replace Magic Number with Symbolic Constant In einer Methode steht eine Zahl (außer 0 und 1). Besser eine benannte Konstante einführen Name ist Dokumentation Wert ist besser änderbar Typcode, Arraylänge o.ä.? Dann Alternative wählen In einer Methode steht eine Zahl (außer 0 und 1). Besser eine benannte Konstante einführen Name ist Dokumentation Wert ist besser änderbar Typcode, Arraylänge o.ä.? Dann Alternative wählen

77 77 Replace Temp with Query Eine temporäre Variable enthält ein Zwischenergebnis. Den entsprechenden Ausdruck in eine Methode auslagern Ursprüngliche Methode wird übersichtlicher Verfügbar im ganzen Objekt Eine temporäre Variable enthält ein Zwischenergebnis. Den entsprechenden Ausdruck in eine Methode auslagern Ursprüngliche Methode wird übersichtlicher Verfügbar im ganzen Objekt

78 78 Rename Method (1) Der Name einer Methode spiegelt nicht (mehr) ihren Inhalt wieder. Den Namen ändern Analog Parameter hinzufügen oder entfernen Der Name einer Methode spiegelt nicht (mehr) ihren Inhalt wieder. Den Namen ändern Analog Parameter hinzufügen oder entfernen

79 79 Rename Method (2) Konkrete Schritte: Basis- und Unterklassen prüfen Methode mit neuem Namen anlegen, Implementierung hineinkopieren, compilieren Clients schrittweise umstellen, jeweils testen Ursprüngliche Methode löschen, Testen Konkrete Schritte: Basis- und Unterklassen prüfen Methode mit neuem Namen anlegen, Implementierung hineinkopieren, compilieren Clients schrittweise umstellen, jeweils testen Ursprüngliche Methode löschen, Testen

80 80 Replace Constructor with Factory Method Konstruktor ist nicht flexibel genug. Besser statische create-Methode verwenden Kontrolle über Instanzierung (Unterklassen, Caching, Referenz-Semantik) Expliziter Name dokumentiert Konstruktor ist nicht flexibel genug. Besser statische create-Methode verwenden Kontrolle über Instanzierung (Unterklassen, Caching, Referenz-Semantik) Expliziter Name dokumentiert

81 81 Extract Method (1) Mehrere Statements einer Methode gehören logisch zusammen. Auslagern in eigene Methode Sprechender Name für die neue Methode Ursprüngliche Methode wird übersichtlicher Mehrere Statements einer Methode gehören logisch zusammen. Auslagern in eigene Methode Sprechender Name für die neue Methode Ursprüngliche Methode wird übersichtlicher

82 82 Extract Method (2) Konkrete Schritte: Neue Methode anlegen und gut benennen Implementierung hineinkopieren Notwendige Parameter anlegen und benennen Ggf. Rückgabewert einführen Compilieren Code in ursprünglicher Methode durch Aufruf ersetzen Konkrete Schritte: Neue Methode anlegen und gut benennen Implementierung hineinkopieren Notwendige Parameter anlegen und benennen Ggf. Rückgabewert einführen Compilieren Code in ursprünglicher Methode durch Aufruf ersetzen

83 83 Inline Method (1) Der Code einer Methode ist genauso klar wie ihr Name. Methode inlinen Unnötige Methode ist nur Ballast Gegenstück zu Extract Method Der Code einer Methode ist genauso klar wie ihr Name. Methode inlinen Unnötige Methode ist nur Ballast Gegenstück zu Extract Method

84 84 Inline Method (2) Konkrete Schritte: Prüfen, dass die Methode nicht polymorph ist Jeden Aufruf durch den Inhalt ersetzen Compilieren und testen Methode löschen Bei Komplikationen nicht inlinen Konkrete Schritte: Prüfen, dass die Methode nicht polymorph ist Jeden Aufruf durch den Inhalt ersetzen Compilieren und testen Methode löschen Bei Komplikationen nicht inlinen

85 85 Remove Assignments to Parameters Eine Methode enthält eine Zuweisung an einen Parameter. Stattdessen temporäre Variable verwenden Erhöht Übersichtlichkeit Eine Methode enthält eine Zuweisung an einen Parameter. Stattdessen temporäre Variable verwenden Erhöht Übersichtlichkeit

86 86 Replace Method with Method Object (1) Eine Methode verwendet lokale Variablen so, dass Extract Method schwierig ist. Neue Klasse anlegen, die der Methode entspricht Lokale Variablen werden zu Attributen Danach ist Refactoring leicht Eine Methode verwendet lokale Variablen so, dass Extract Method schwierig ist. Neue Klasse anlegen, die der Methode entspricht Lokale Variablen werden zu Attributen Danach ist Refactoring leicht

87 87 Replace Method with Method Object (2) Konkrete Schritte: Neue Klasse anlegen Referenz auf ursprüngliche Klasse sowie Attribute für die lokalen Variablen einführen Konstruktor zur Initialisierung Methode compute einführen und die ursprüngliche Implementierung hineinkopieren In der alten Methode an die neue delegieren Konkrete Schritte: Neue Klasse anlegen Referenz auf ursprüngliche Klasse sowie Attribute für die lokalen Variablen einführen Konstruktor zur Initialisierung Methode compute einführen und die ursprüngliche Implementierung hineinkopieren In der alten Methode an die neue delegieren

88 88 Substitute Algorithm Ein Algorithmus ist komplizierter als nötig. Durch einen einfacheren Algorithmus ersetzen Insbesondere, wenn zwei verschiedene Algorithmen für das Gleiche verwendet werden Optimierung allenfalls am Ende Ein Algorithmus ist komplizierter als nötig. Durch einen einfacheren Algorithmus ersetzen Insbesondere, wenn zwei verschiedene Algorithmen für das Gleiche verwendet werden Optimierung allenfalls am Ende

89 89 Move Method (1) Eine Methode benutzt mehr Features oder wird von mehr Features einer anderen Klasse benutzt als der, wo sie definiert ist. Methode zu den Features verschieben Stärkere Kohäsion, schlankere Schnittstellen Das Original delegiert oder wird gelöscht Eine Methode benutzt mehr Features oder wird von mehr Features einer anderen Klasse benutzt als der, wo sie definiert ist. Methode zu den Features verschieben Stärkere Kohäsion, schlankere Schnittstellen Das Original delegiert oder wird gelöscht

90 90 Move Method (2) Konkrete Schritte: Benutzte Felder und Methoden ggf. mitverschieben Vererbungshierarchie prüfen Methode in der neuen Klasse deklarieren Implementierung hineinkopieren und anpassen Compilieren Aufrufe ändern oder alte Methode umbiegen Konkrete Schritte: Benutzte Felder und Methoden ggf. mitverschieben Vererbungshierarchie prüfen Methode in der neuen Klasse deklarieren Implementierung hineinkopieren und anpassen Compilieren Aufrufe ändern oder alte Methode umbiegen

91 91 Move Field (1) Ein Feld wird in einer anderen Klasse mehr benutzt Dorthin verschieben Bessere Kohäsion und schlankere Schnittstelle Eventuell Methoden mitverschieben Ein Feld wird in einer anderen Klasse mehr benutzt Dorthin verschieben Bessere Kohäsion und schlankere Schnittstelle Eventuell Methoden mitverschieben

92 92 Move Field (2) Konkrete Schritte: In Zielklasse ein Feld mit get- und set-Methode anlegen Navigation von alter zu neuer Klasse sicherstellen Ursprüngliches Feld entfernen Zugriffe umbiegen (inkl. Unterklassen) Compilieren und testen Konkrete Schritte: In Zielklasse ein Feld mit get- und set-Methode anlegen Navigation von alter zu neuer Klasse sicherstellen Ursprüngliches Feld entfernen Zugriffe umbiegen (inkl. Unterklassen) Compilieren und testen

93 93 Extract Class (1) Eine Klasse macht die Arbeit von zweien. Neue Klasse anlegen und Felder und Methoden hineinverschieben Übersichtlichkeit durch klare Aufgabenteilung Eine Klasse macht die Arbeit von zweien. Neue Klasse anlegen und Felder und Methoden hineinverschieben Übersichtlichkeit durch klare Aufgabenteilung

94 94 Extract Class (2) Konkrete Schritte: Aufteilung planen Neue Klasse anlegen, Referenz von alter zu neuer Einzelne Felder und Methoden verschieben Schnittstellen überarbeiten Ggf. neue Klasse veröffentlichen (Referenz/Wert) Konkrete Schritte: Aufteilung planen Neue Klasse anlegen, Referenz von alter zu neuer Einzelne Felder und Methoden verschieben Schnittstellen überarbeiten Ggf. neue Klasse veröffentlichen (Referenz/Wert)

95 95 Hide Delegate Ein Client holt sich von einem Objekt ein anderes Objekt und ruft darauf eine Methode auf. Im ersten Objekt eine Methode erzeugen, die dann delegiert Dadurch bessere Kapselung Ein Client holt sich von einem Objekt ein anderes Objekt und ruft darauf eine Methode auf. Im ersten Objekt eine Methode erzeugen, die dann delegiert Dadurch bessere Kapselung

96 96 Remove Middle Man Eine Klasse delegiert eine Reihe von Aufrufen einfach an ein anderes Objekt. Stattdessen inneres Objekt herausreichen get-Methode einführen Dadurch Übersichtlichkeit erhöhen Eine Klasse delegiert eine Reihe von Aufrufen einfach an ein anderes Objekt. Stattdessen inneres Objekt herausreichen get-Methode einführen Dadurch Übersichtlichkeit erhöhen

97 97 Replace Data Value with Object Ein primitives Attribut hat eigentlich dazugehörige Funktionalität. Spezielle Klasse schaffen und deren Instanz verwenden Clients nach und nach umstellen Wert-Semantik: Identität spielt keine Rolle Ein primitives Attribut hat eigentlich dazugehörige Funktionalität. Spezielle Klasse schaffen und deren Instanz verwenden Clients nach und nach umstellen Wert-Semantik: Identität spielt keine Rolle

98 98 Replace Type Code with Subclass (1) Eine Klasse hat einen Typcode, der über das Verhalten entscheidet. Für jeden Wert des Typcodes eine Unterklasse Grundlage für weitere Refactorings Eine Klasse hat einen Typcode, der über das Verhalten entscheidet. Für jeden Wert des Typcodes eine Unterklasse Grundlage für weitere Refactorings

99 99 Replace Type Code with Subclass (2) Konkrete Schritte: Auf Typcode nur durch get-Methode zugreifen statische create-Methode einführen Für jeden Wert eine Unterklasse einführen, die die get-Methode überschreibt Typcode-Attribut aus der Basisklasse entfernen Konkrete Schritte: Auf Typcode nur durch get-Methode zugreifen statische create-Methode einführen Für jeden Wert eine Unterklasse einführen, die die get-Methode überschreibt Typcode-Attribut aus der Basisklasse entfernen

100 100 Replace Type Code with State/Strategy (1) Ein Typ-Code entscheidet über Verhalten, aber es gibt schon Unterklassen. Zweite Vererbungshierarchie für Typ-Code Als State/Strategy anbinden Ein Typ-Code entscheidet über Verhalten, aber es gibt schon Unterklassen. Zweite Vererbungshierarchie für Typ-Code Als State/Strategy anbinden

101 101 Replace Type Code with State/Strategy (2) Konkrete Schritte: Den Typ-Code hinter get-Methode kapseln Neue Klasse mit Unterklassen für jeden Wert schaffen (State-Klasse) Typ-Code in die neue Klassenhierarchie verschieben Beim Setzen des Typ-Codes stattdessen State ändern Typ-Feld entfernen Konkrete Schritte: Den Typ-Code hinter get-Methode kapseln Neue Klasse mit Unterklassen für jeden Wert schaffen (State-Klasse) Typ-Code in die neue Klassenhierarchie verschieben Beim Setzen des Typ-Codes stattdessen State ändern Typ-Feld entfernen

102 102 Replace Conditional with Polymorphism (1) Verhalten wird über einen Typ-Code ausgewählt. Für jeden Typcode eine Unterklasse Spezifisches Verhalten jeweils in einer überschriebenen Methode Man vergisst keine Fälle und gruppiert Logik Verhalten wird über einen Typ-Code ausgewählt. Für jeden Typcode eine Unterklasse Spezifisches Verhalten jeweils in einer überschriebenen Methode Man vergisst keine Fälle und gruppiert Logik

103 103 Replace Conditional with Polymorphism (2) Konkrete Schritte: Replace Type Code with... Ggf. Fallunterscheidung in eigene Methode Der Reihe nach: Für Unterklassen die Methode überschreiben und testen Den Fall aus der ursprünglichen Methode entfernen und testen Methode in der Basisklasse abstrakt machen Konkrete Schritte: Replace Type Code with... Ggf. Fallunterscheidung in eigene Methode Der Reihe nach: Für Unterklassen die Methode überschreiben und testen Den Fall aus der ursprünglichen Methode entfernen und testen Methode in der Basisklasse abstrakt machen

104 104 Replace Subclass with Fields (1) Unterklassen unterscheiden sich nur in Methoden, die konstante Werte liefern. Die Unterklassen entfernen und die Werte aus Attributen holen Die Unterklassen sind unnötiger Ballast geworden Unterklassen unterscheiden sich nur in Methoden, die konstante Werte liefern. Die Unterklassen entfernen und die Werte aus Attributen holen Die Unterklassen sind unnötiger Ballast geworden

105 105 Replace Subclass with Fields (2) Konkrete Schritte: Statische create-Methode einführen final Felder in der Basisklasse einführen mit protected Konstruktor, der sie initialisiert Unterklassen so ändern, dass sie diesen aufrufen Die Methoden in der Basisklasse ändern, so dass sie die Werte der Felder liefern Unterklassen entfernen Konkrete Schritte: Statische create-Methode einführen final Felder in der Basisklasse einführen mit protected Konstruktor, der sie initialisiert Unterklassen so ändern, dass sie diesen aufrufen Die Methoden in der Basisklasse ändern, so dass sie die Werte der Felder liefern Unterklassen entfernen

106 106 Consolidate Duplicate Conditional Fragments Ein gemeinsames Stück Code ist in allen Zweigen einer Fallunterscheidung. Gemeinsamen Code herausziehen Entweder davor oder dahinter Sonst eventuell in eigene Methode Ein gemeinsames Stück Code ist in allen Zweigen einer Fallunterscheidung. Gemeinsamen Code herausziehen Entweder davor oder dahinter Sonst eventuell in eigene Methode

107 107 Remove Control Flag Ein Flag kontrolliert den Ablauf einer Schleife. Besser break, continue und return verwenden Kürzer und übersichtlicher Ein Flag kontrolliert den Ablauf einer Schleife. Besser break, continue und return verwenden Kürzer und übersichtlicher

108 108 Replace Nested Conditional with Guard Clause Eine Methode hat verschachtelte if- Statements, um ohne zweites return auszukommen. Sonderfälle am Anfang behandeln und dort direkt zurückkehren Prüflogik in eigene Methoden auslagern Normalfall wird explizit Eine Methode hat verschachtelte if- Statements, um ohne zweites return auszukommen. Sonderfälle am Anfang behandeln und dort direkt zurückkehren Prüflogik in eigene Methoden auslagern Normalfall wird explizit

109 109 Separate Query from Modifier (1) Eine Methode führt eine Abfrage durch und ändert gleichzeitig den Zustand des Objekts. Aufspalten in reine Abfrage und Modifikation Reine Abfrage ist vielseitig einsetzbar und leicht zu verstehen Optimieren allenfalls später Multithreading / Remote: Sonderfälle Eine Methode führt eine Abfrage durch und ändert gleichzeitig den Zustand des Objekts. Aufspalten in reine Abfrage und Modifikation Reine Abfrage ist vielseitig einsetzbar und leicht zu verstehen Optimieren allenfalls später Multithreading / Remote: Sonderfälle

110 110 Separate Query from Modifier (2) Konkrete Schritte: Die reine Abfrage als eigene Methode bauen In der ursprünglichen Methode das Ergebnis der Abfrage zurückgeben Compilieren und testen In Aufrufen die Abfrage in eigenen Aufruf vor die alte Methode setzen Rückgabe der alten Methode entfernen Konkrete Schritte: Die reine Abfrage als eigene Methode bauen In der ursprünglichen Methode das Ergebnis der Abfrage zurückgeben Compilieren und testen In Aufrufen die Abfrage in eigenen Aufruf vor die alte Methode setzen Rückgabe der alten Methode entfernen

111 111 Parameterize Method Mehrere Methoden tun das Gleiche mit unterschiedlichen fest verdrahteten Werten. Zusammenführen in eine einzige Methode mit Parameter Vermeidet Code-Duplizierung Mehrere Methoden tun das Gleiche mit unterschiedlichen fest verdrahteten Werten. Zusammenführen in eine einzige Methode mit Parameter Vermeidet Code-Duplizierung

112 112 Replace Parameter with Explicit Methods Ein Methode macht völlig verschiedene Dinge abhängig vom Wert eines Parameters. In mehrere Methoden mit sprechenden Namen zerlegen Ein Methode macht völlig verschiedene Dinge abhängig vom Wert eines Parameters. In mehrere Methoden mit sprechenden Namen zerlegen

113 113 Preserve Whole Object Eine Methode bekommt mehrere Attribute des gleichen Objekts als Parameter. Besser das ganze Objekt als Parameter hineinreichen Außer man will bewusst entkoppeln Eine Methode bekommt mehrere Attribute des gleichen Objekts als Parameter. Besser das ganze Objekt als Parameter hineinreichen Außer man will bewusst entkoppeln

114 114 Replace Parameter with Method Eine Methode bekommt einen Parameter, den sie auch selbst ermitteln könnte. Parameter ermitteln und aus der Signatur entfernen Durch Methode von this oder von einem anderen Parameter Eine Methode bekommt einen Parameter, den sie auch selbst ermitteln könnte. Parameter ermitteln und aus der Signatur entfernen Durch Methode von this oder von einem anderen Parameter

115 115 Introduce Parameter Object (1) Mehrere Parameter bilden eine natürliche Einheit. Zu einem neuen Typ zusammenfassen Wertsemantik Typsicher, besser lesbar Mehrere Parameter bilden eine natürliche Einheit. Zu einem neuen Typ zusammenfassen Wertsemantik Typsicher, besser lesbar

116 116 Introduce Parameter Object (2) Konkrete Schritte: Neue Klasse leer anlegen Die Parameter als Attribute hinzufügen. Dabei die Werte immutable machen Den jeweiligen Parameter aus dem Aufruf entfernen. Compilieren und Testen Funktionalität in die neue Klasse extrahieren Konkrete Schritte: Neue Klasse leer anlegen Die Parameter als Attribute hinzufügen. Dabei die Werte immutable machen Den jeweiligen Parameter aus dem Aufruf entfernen. Compilieren und Testen Funktionalität in die neue Klasse extrahieren

117 117 Remove Setting Method Ein Feld wird nur bei der Erzeugung gesetzt und anschließend nicht mehr geändert. Ggf. Konstruktor einführen Set-Methode entfernen Feld final machen Ein Feld wird nur bei der Erzeugung gesetzt und anschließend nicht mehr geändert. Ggf. Konstruktor einführen Set-Methode entfernen Feld final machen

118 118 Encapsulate Downcast Eine Methode liefert eine Referenz, die erst nach Downcast verwendbar ist (z.B. ein Element einer Collection). Downcast in der Methode durchführen und den richtigen Typ zurückliefern Erhöht die Übersichtlichkeit und Typsicherheit Eine Methode liefert eine Referenz, die erst nach Downcast verwendbar ist (z.B. ein Element einer Collection). Downcast in der Methode durchführen und den richtigen Typ zurückliefern Erhöht die Übersichtlichkeit und Typsicherheit

119 119 Pull Up Method Unterklassen haben Methoden mit dem gleichen Ergebnis. Methoden in die Basisklasse verschieben Code-Duplizierung vermeiden Eventuell unterschiedliche Algorithmen Unterklassen haben Methoden mit dem gleichen Ergebnis. Methoden in die Basisklasse verschieben Code-Duplizierung vermeiden Eventuell unterschiedliche Algorithmen

120 120 Push Down Method Eine Methode der Basisklasse wird nur von einer Unterklasse verwendet. Die Methode in diese Unterklasse verschieben Macht die Basisklasse einfacher Dokumentiert die Abhängigkeiten Eine Methode der Basisklasse wird nur von einer Unterklasse verwendet. Die Methode in diese Unterklasse verschieben Macht die Basisklasse einfacher Dokumentiert die Abhängigkeiten

121 121 Extract Superclass Mehrere Klassen haben teilweise die gleichen Methoden. Gemeinsamkeiten in eine Basisklasse ziehen Dokumentiert Beziehung zwischen den Klassen Öffnet den Blick für Verwendung dieser neuen Abstraktion Mehrere Klassen haben teilweise die gleichen Methoden. Gemeinsamkeiten in eine Basisklasse ziehen Dokumentiert Beziehung zwischen den Klassen Öffnet den Blick für Verwendung dieser neuen Abstraktion

122 122 Form Template Method (1) Unterklassen haben Methoden, die ähnliche Schritte in der gleichen Reihenfolge durchführen. Methoden extrahieren für Schritte, die von einer neuen Methode der Basisklasse aufgerufen werden Vermeidet Code-Duplizierung, dokumentiert Beziehungen Unterklassen haben Methoden, die ähnliche Schritte in der gleichen Reihenfolge durchführen. Methoden extrahieren für Schritte, die von einer neuen Methode der Basisklasse aufgerufen werden Vermeidet Code-Duplizierung, dokumentiert Beziehungen

123 123 Form Template Method (2) Konkrete Schritte: Methoden zerlegen Methodensignaturen vereinheitlichen Jeweils compilieren und testen Ursprüngliche Methode in Basisklasse ziehen Konkrete Schritte: Methoden zerlegen Methodensignaturen vereinheitlichen Jeweils compilieren und testen Ursprüngliche Methode in Basisklasse ziehen

124 124 Replace Inheritance with Delegation Eine Unterklasse will nur einen Teil der Schnittstelle der Basisklasse haben. Besser Aufrufe an eine Instanz der Basisklasse durchreichen Klarere Beziehungen: Vererbung legt Polymorphie nahe Eine Unterklasse will nur einen Teil der Schnittstelle der Basisklasse haben. Besser Aufrufe an eine Instanz der Basisklasse durchreichen Klarere Beziehungen: Vererbung legt Polymorphie nahe

125 125 Der Code ist das Design Alle hier präsentierten Refactorings wollen das Design im Quelltext klarer ausdrücken. Namen sind sehr wichtig Klarheit und Einfachheit Compilerunterstützung Diese Ziele sind wichtiger als das Verwenden konkreter Refactorings! Alle hier präsentierten Refactorings wollen das Design im Quelltext klarer ausdrücken. Namen sind sehr wichtig Klarheit und Einfachheit Compilerunterstützung Diese Ziele sind wichtiger als das Verwenden konkreter Refactorings!

126 126 Übersicht Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung

127 127 Beispiel Ein praktisches Beispiel der Refactorings Der Quelltext ist im Internet verfügbar: Ein praktisches Beispiel der Refactorings Der Quelltext ist im Internet verfügbar:

128 128 Übersicht Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung Einführung Das Umfeld für Refactoring Code Smells als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung

129 129 Toolunterstütztes Refactoring Die Durchführung des Refactoring lässt sich weitgehend automatisieren. Schutz vor Flüchtigkeitsfehlern Mehr als Suchen und Ersetzen Plausibilitätsprüfungen Die Durchführung des Refactoring lässt sich weitgehend automatisieren. Schutz vor Flüchtigkeitsfehlern Mehr als Suchen und Ersetzen Plausibilitätsprüfungen

130 130 Kriterien für Toolauswahl Folgende Punkte stellen Kriterien für die Auswahl eines Refactoring-Tools dar: Zuverlässigkeit Integration mit IDE Auf dem Parse-Baum operieren (Extract Method als Indiz) Geschwindigkeit Folgende Punkte stellen Kriterien für die Auswahl eines Refactoring-Tools dar: Zuverlässigkeit Integration mit IDE Auf dem Parse-Baum operieren (Extract Method als Indiz) Geschwindigkeit

131 131 Refactoring-Tools Hier eine Auswahl von aktuellen Refactoring-Tools für Java: Idea (www.intellij.com) Xrefactory (xref-tech.com/speller) Eclipse (www.eclipse.org)... Hier eine Auswahl von aktuellen Refactoring-Tools für Java: Idea (www.intellij.com) Xrefactory (xref-tech.com/speller) Eclipse (www.eclipse.org)...

132 132 Toolunterstützung praktisch Demonstration für toolgestütztes Refactoring So einfach kann Refactoring in der Praxis sein. Demonstration für toolgestütztes Refactoring So einfach kann Refactoring in der Praxis sein.

133 133 Literatur Folgende Quellen sind gute Startpunkte für eine Vertiefung: Refactoring, Martin Fowler Extreme Programming Explained, Kent Beck Folgende Quellen sind gute Startpunkte für eine Vertiefung: Refactoring, Martin Fowler Extreme Programming Explained, Kent Beck

134 134 Zusammenfassung Refactoring Das Umfeld von Refactoring Code Smells JUnit Refactoring-Katalog Toolunterstützung Refactoring Das Umfeld von Refactoring Code Smells JUnit Refactoring-Katalog Toolunterstützung


Herunterladen ppt "Refactoring Java Code"

Ähnliche Präsentationen


Google-Anzeigen