Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Refactoring (Refaktorisierung) Seminar Programmierstil Klemens Stelzmüller WS 2002.

Ähnliche Präsentationen


Präsentation zum Thema: "Refactoring (Refaktorisierung) Seminar Programmierstil Klemens Stelzmüller WS 2002."—  Präsentation transkript:

1 Refactoring (Refaktorisierung) Seminar Programmierstil Klemens Stelzmüller WS 2002

2 Was ist Refactoring? [Fowl00] Refaktorisierung (Substantiv): Eine Änderung an der internen Struktur einer Software, um sie leichter verständlich zu machen und einfacher zu verändern, ohne ihr beobachtbares Verhalten zu ändern. Refaktorisieren (Verb): Eine Software umstrukturieren, ohne ihr beobachtbares Verhalten zu ändern, indem man eine Reihe von Refaktorisierungen anwendet. Refaktorisieren gibt mir die Freiheit, meine Meinung zu ändern!

3 Gründe für den Einsatz Warum soll man refaktorisieren? Verbesserung & Pflege des Designs Software wird verständlicher Fehler werden gefunden Hilfe, um schneller zu programmieren Wann soll man refaktorisieren? Beim Hinzufügen neuer Funktionalität Bei der Fehlersuche & -behebung Code-Reviews

4 Wo einsetzen? Bad Smells Bad SmellAbhilfe Duplizierter CodeMethode extrahieren Template Methode bilden Lange MethodeMethode extrahieren NeidMethode extrahieren Methode verschieben Temp. VariableTemp. Variable durch Abfrage ersetzen Switch-StatementsTypenschl. durch Unterklassen ers. Anderer Gestank Katalog nach Fowler! [Fowl00] If it stinks, change it – Kent Beck

5 Wie einsetzen? Umfangreiche Testsuite aufbauen (Bsp: xUnit-Familie) Refaktorisierungen in kleinen Schritten durchführen Stellen mit größtem Gestank auswählen Nach jeder Änderung testen keine Änderungen am Verhalten! Bei Erfolg weitermachen Bei Fehlern von vorne beginnen – nicht Fehler suchen! Die 2 Hüte nicht vergessen!

6 Beispiel Videoverleih Rechnungen für Kunden erstellen & drucken Welche Filme wie lange ausgeliehen Miete abhängig von der Art des Films Regulär Neuerscheinung Kinderfilm Zusätzlich Bonuspunkte

7 Problem: Customer.Statement public string Statement { get { double totalAmount = 0.0; int frequentRenterPoints = 0; string result = "Rental Record for " + Name + "\n"; foreach(Rental rental in rentals) { double thisAmount = 0.0; switch(rental.Movie.PriceCode) { case MoviePriceCode.Regular: thisAmount += 2; if(rental.DaysRented > 2) thisAmount += (rental.DaysRented - 2) * 1.5; break; case MoviePriceCode.NewRelease: thisAmount += rental.DaysRented * 3; break; case MoviePriceCode.Childrens: thisAmount += 1.5; if(rental.DaysRented > 3) thisAmount += (rental.DaysRented - 3) * 1.5; break; } Beträge/Zeile ermitteln Kopfzeile füllen

8 Problem: Customer.Statement frequentRenterPoints++; if(rental.Movie.PriceCode == MoviePriceCode.NewRelease && rental.DaysRented > 1) frequentRenterPoints++; result += "\t" + rental.Movie.Title + "\t" + thisAmount+ "\n"; totalAmount += thisAmount; } result += "Amount owed is " + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + " frequent renter pts"; return result; } In anderen Klassen sollte geschehen: Preise abhängig von Film-Art berechnen Bonuspunkte abhängig von Film-Art berechnen Erschwert Erweiterung (HTML-Rechnung) Bonuspunkte berechnen Fußzeile füllen Rechnungs- zeile füllen

9 Refaktorisierungen im Detail 1. Methode extrahieren (aus Statement) Switch nach AmountFor ziehen 2. Methode verschieben AmountFor nach Rental kopieren, Wrapper einrichten Wrapper durch tatsächlichen Aufruf ersetzen 3. Temp. Variable durch Abfrage ersetzen thisAmount aus Statement entfernen 4. Methode extrahieren & verschieben Berechnung der Bonuspunkte nach Rental ziehen 5. Temp. Variable durch Abfrage ersetzen totalAmount & frequentRenterPoints entfernen

10 1) Methode extrahieren private double AmountFor(Rental rental) { double thisAmount = 0; switch(rental.Movie.PriceCode) { case MoviePriceCode.Regular: thisAmount += 2; if(rental.DaysRented > 2) thisAmount += (rental.DaysRented - 2) * 1.5; break; case MoviePriceCode.NewRelease: thisAmount += rental.DaysRented * 3; break; case MoviePriceCode.Childrens: thisAmount += 1.5; if(rental.DaysRented > 3) thisAmount += (rental.DaysRented - 3) * 1.5; break; } return thisAmount; } Switch nach AmountFor ziehen:

11 1) Methode extrahieren public string Statement { get { double totalAmount = 0.0; int frequentRenterPoints = 0; string result = "Rental Record for " + Name + "\n"; foreach(Rental rental in rentals) { double thisAmount = 0.0; thisAmount = AmountFor(rental); frequentRenterPoints++; if(rental.Movie.PriceCode == MoviePriceCode.NewRelease && rental.DaysRented > 1) frequentRenterPoints++; result += "\t" + rental.Movie.Title + "\t" + thisAmount + "\n"; totalAmount += thisAmount; } result += "Amount owed is " + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + " frequent renter pts"; return result; } AmountFor statt Switch benutzen:

12 2) Methode verschieben Als Charge in Rental einfügen:

13 3) Temp. Variable als Abfrage thisAmount aus Statement entfernen: public string Statement { get { double totalAmount = 0.0; int frequentRenterPoints = 0; string result = "Rental Record for " + Name + "\n"; foreach(Rental rental in rentals) { frequentRenterPoints++; if(rental.Movie.PriceCode == MoviePriceCode.NewRelease && rental.DaysRented > 1) frequentRenterPoints++; result += "\t" + rental.Movie.Title + "\t" + rental.Charge + "\n"; totalAmount += rental.Charge; } result += "Amount owed is " + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + " frequent renter pts"; return result; }

14 4) Methode extrah. & versch. Berechnung der Bonus- punkte nach Rental:

15 5) Temp. Variable als Abfrage public string Statement { get { string result = "Rental Record for " + Name + "\n"; foreach(Rental rental in rentals) { result += "\t" + rental.Movie.Title + "\t" + rental.Charge + "\n"; } result += "Amount owed is " + TotalCharge + "\n"; result += "You earned " + TotalFrequentRenterPoints + " frequent renter pts"; return result; } totalAmount & frequentRenterPoints entfernen:

16 6) Erweiterung einführen Die HTML-Rechnung einbauen: public string HtmlStatement { get { string result = " Rentals for " + Name + " "; foreach(Rental rental in rentals) { result += rental.Movie.Title + ": " + rental.Charge + " \n"; } result += " Amount owed is " + TotalCharge + " \n"; result += "You earned " + TotalFrequentRenterPoints + " frequent renter points "; return result; }

17 Und danach? Switch refaktorisieren Berechnungen nach Movie Zustandsmuster für Arten Vererbung Polymorphismus Verwendung in Customer einarbeiten

18 Probleme in der Praxis Skepsis der Entwickler & Manager Zeitlicher Aufwand & Kosten Nutzen nicht unmittelbar ersichtlich Refaktorisierung nicht immer möglich Wahl zwischen verschiedenen Alternativen schwierig Globale Auswirkungen eines Schrittes oft lokal nicht abschätzbar Aufklärung, Erfahrung & Werkzeuge

19 Literatur Martin Fowler: Refactoring – Wie Sie das Design vorhandener Software verbessern, Addison-Wesley, 2000 [Fowl00] William C. Wake: Refactoring Workbook, Draft Martin Fowler, Refactoring Home Page Einfach nach Refactoring googlen


Herunterladen ppt "Refactoring (Refaktorisierung) Seminar Programmierstil Klemens Stelzmüller WS 2002."

Ähnliche Präsentationen


Google-Anzeigen