1 / 134

Refactoring Java Code

Refactoring Java Code. Arno.Haase@Haase-Consulting.com Arno.Haase@acm.org www.Haase-Consulting.com. Übersicht.  Einführung Das Umfeld für Refactoring „Code Smells“ als Wegweiser Automatisierte Tests mit JUnit Konkrete Refactorings Beispiel Toolunterstützung.

banyan
Download Presentation

Refactoring Java Code

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Refactoring Java Code Arno.Haase@Haase-Consulting.com Arno.Haase@acm.org www.Haase-Consulting.com

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

  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

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

  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

  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

  7. Demonstration • Ein Quelltext sagt mehr als tausend Folien... • Der Quelltext ist im Internet verfügbar: www.haase-consulting.com/download/oop2002

  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

  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

  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

  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

  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.

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

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

  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)

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

  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

  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.

  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

  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

  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.

  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“

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

  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

  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

  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.“

  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

  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

  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.

  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...

  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

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

  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!

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

  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?

  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

  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

  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

  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

  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

  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

  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

  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

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

  45. 5$ 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  +

  46. 5$ 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 

  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

  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

  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

  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

More Related