Refaktoryzacja Na podstawie www.refactoring.com 1
Plan Refaktoryzacja Co to jest Ogólne zasady i wskazówki Katalog refaktoryzacji Narzędzia (Eclipse, IntelliJ) 2
Co to jest refaktoryzacja Proces zmian oprogramowania, w sposób nie naruszający zewnętrznego zachowania, ale ulepszający wewnętrzną strukturę Uporządkowany sposób ulepszania i oczyszczania kodu, minimalizując powstawanie błędów Ulepszanie stylu istniejącego programu, w celu polepszenia czytelności i łatwości zmian Proces odwrotny do naturalnej degradacji jakości kodu Składa się z małych, prostch kroków Implementacja wpływa na projektowanie 3
Przykład parametryzowanie metody Utwórz nową metodę Skompiluj program Zastąp implementację jednej z metod wywołaniem nowej Skompiluj i przetestuj Zastąp wywołania starej nową i usuń starą Powtórz dla wszystkich starych metod 4
Wskazówki Gdy chcesz dodać element do programu, a nie da się tego wygodnie zrobić, najpierw zrefaktoryzuj, aby było wygodnie i wtedy dodaj. Zanim zaczniesz refaktoryzować, upewnij się, że masz zestaw testów Testy powinny być samosprawdzające (np. wypisywac OK) Rytm: test, mała zmiana, test, mała zmiana, test... 5
Podział prac Podczas dodawania nowej funkcjonalności nie należy zmieniać istniejącego kodu Podczas refaktoryzacji nie wolno zmieniać (dodawać funkcjonalności) Częste przejścia między tymi dwiema czynnościami W każdej chwili trzeba pamiętać, którą z nich aktualnie się zajmujemy 6
Dlaczego refaktoryzować Ulepszanie projektu programu Ciągłe zmiany wpływają na pogarszanie jakości kodu Źle zaprojektowany program jest trudny do modyfikacji Refactoring ułatwia zrozumienie programu Rozmowa z kodem adresatem jest nie tylko komputer, ale też inni programiści Komputer wszystko przyjmie, ale człowiek nie 7
Dodatkowe zalety Refactoring pomaga znaleźć błedy Ułatwia zrozumienie kodu Wyjaśnianie struktury i znaczenia kodu Przy okazji wychwytuje się błędy Pomaga programować szybciej Pozornie sprzeczne, ale... Dobrze zaprojektowany program przyspiesza implementację Szybciej można wprowadzać zmiany 8
Kiedy refaktoryzować Cały czas - kiedy taka zmiana coś nam ułatwi Reguła trzech Gdy robisz coś po raz pierwszy, to po prostu to robisz Gdy robisz coś podobnego po raz drugi, to niechętnie, ale duplikujesz rozwiązanie Gdy robisz coś prodobnego po raz trzeci, zaczynasz refaktoryzować Przed dodaniem nowej funkcjonalności Podczas recenzji kodu Podczas naprawiania błędu 9
Problemy z refaktoryzacją Bazy danych Trudna w zmianie struktura bazy Zmiana interfejsu Gdy nie możemy zmienić publicznego interfejsu, ponieważ nie znamy wszystkich jego użytkowników Można pozostawić stary interfejs Wskazówka: nie publikuj interfejsów przedwcześnie Czasem łatwiej jest napisać coś od nowa Zbyt skomplikowany kod do wyrzucenia! 10
Refaktoryzaja a projektowanie Można całkowicie zrezygnować z projektowania na korzyść refaktoryzacji Można uprościć fazę projektowania na korzyść refaktoryzacji Zamiast elastycznych, ogólnych rozwiązań prostota i łatwość zmian 11
Refaktoryzacja a optymalizacja Najpierw tworzymy dobrze zaprojektowany program Później mierzymy wydajność profilerem Program spędza najwięcej czasu w małych fragmentach kodu i to je optymalizujemy Dobry kod łatwo optymalizować (wprowadzanie zmian!) 12
Kiedy coś podejrzanie pachnie... w kodzie Powtórzenia w kodzie Długie metody Duże klasy Długie listy parametrów Rozbieżne zmiany Grupki danych Obsesja typów prostych Instrukcja switch/case Równoległe dziedziczenie Leniwe klasy Wątpliwe uogólnianie Tymczasowe pola Łańcuchy wywołań Pośrednik Alternatywne klasy z różnymi interfejsami Niekompletne klasy biblioteczne Klasy-dane 13
Testy Powinny być automatyczne i powinny same sprawdzać swoje wyniki Potężne narzędzie do wykrywania błędów, zapewniające zwrot zainwestowanego czasu Przykład bibioteka JUnit 14
Katalog refaktoryzacji 15
Wyciągnięcie metody void printowing() { } printbanner(); //print details System.out.println ("name: " + _name); System.out.println ("amount " + getoutstanding()); void printowing() { } printbanner(); printdetails(getoutstanding()); void printdetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); } 16
Wyciągnięcie klasy 17
Zastąpienie wartości obiektem 18
Usuwanie magicznych liczb double potentialenergy(double mass, double height) { return mass * 9.81 * height; } double potentialenergy(double mass, double height) { return mass * GRAVITATIONAL_CONSTANT * height; } static final double GRAVITATIONAL_CONSTANT = 9.81; 19
Ukrycie delegata <> usunięcie pośrednika 20
Lokalne rozszerzenie Gdy nie możemy zmodyfikować klasy bibliotecznej 21
Schowanie pola public String _name private String _name; public String getname() {return _name;} public void setname(string arg) {_name = arg;} 22
Rozłożenie warunków if (date.before (SUMMER_START) date.after(summer_end)) charge = quantity * _winterrate + _winterservicecharge; else charge = quantity * _summerrate; if (notsummer(date)) charge = wintercharge(quantity); else charge = summercharge (quantity); 23
Wprowadzenie obiektu null if (customer == null) plan = BillingPlan.basic(); else plan = customer.getplan(); 24
Zmiana nazwy metody 25
Obiekt parametrowy 26
Wyciągnięcie pola do góry 27
Narzędzia do refaktoringu Zintegrowane z IDE (Eclipse, JBuilder, etc.) Automatycznie wyszukują referencje do zmieniamych obiektów Ułatwiają unikać błędów Undo/redo możliwość eksperymentowania z kodem 28
Podsumowanie Rozdzielenie refaktoryzacji od dodawania funkcjonalności Ciągłe ulepszanie projektu Małe, kontrolowane kroki Testy na każdym etapie 29
Dalsza lektura http://www.refactoring.com/ Refaktoryzacja. Ulepszanie struktury istniejącego kodu Martin Fowler i inni, 2006, WNT 30