Refaktoryzacja czyli odświeżanie kodu Łukasz Olek Dzięki uprzejmości Bartka Waltera
Motto „Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” Martin Fowler
Więcej funkcji!
Przykre zapachy If it stinks, change it babcia Kenta Becka o strategii zmiany pieluch u niemowląt
Kod, który cuchnie.... Przykłady zapachów duplikaty w kodzie długie metody duże klasy długie listy parametrów złożone instrukcje warunkowe i wiele innych...
Refaktoryzacja Refaktoryzacja to: zmiana wewnętrznej struktury kodu która czyni go czytelniejszym i łatwiejszym w modyfikacji jednak nie zmienia jego obserwowalnego zachowania void doSth() void doSth()
Przykłady refaktoryzacji Extract Method void oblicz () { // oblicz X // oblicz Y wyswietl(X, Y); // zapisz X // zapisz Y } void wyswietl(X,Y) { // wyświetl X // wyświetl Y void obliczINapisz() { // oblicz X // oblicz Y ... // wyświetl X // wyświetl Y // zapisz X // zapisz Y } Jedna metoda – jedna funkcja Lokalizacja potencjalnych błędów
Szablon refaktoryzacji wg Fowlera Nazwa Podsumowanie Cel Mechanika Przykłady
Szablon refaktoryzacji wg Fowlera Nazwa Extract Method Podsumowanie Utworzenie z fragmentu kodu nowej metody Cel Wyłączenie tego fragmentu i utworzenie metody Mechanika utwórz nową metodę i skopiuj do niej fragment kodu sprawdź, czy zmienne lokalne są modyfikowane przekaż zmienne lokalne do nowej metody zastąp kod wywołaniem nowej metody skompiluj i przetestuj Przykłady ...
Najważniejszy podział refaktoryzacji PROSTE TRUDNE Weryfikacja automatyczna Zaimplementowane w wielu IDE Weryfikacja wymaga testów Ręczne... Czym jest serwlet?
Refaktoryzacje proste... Weryfikacja warunków wstępnych i końcowych Analiza statyczna kodu void doSth() void doSth() Czym jest serwlet? Jeżeli przed.... Jeżeli przed.... Jeżeli po.... Jeżeli po....
... i refaktoryzacje trudne Analiza statyczna kodu, warunki wstępne i końcowe Testowanie void doSth() Jeżeli przed.... Jeżeli przed.... Jeżeli po.... Jeżeli po.... Czym jest serwlet?
Refaktoryzacje proste Weryfikacja warunków wstępnych i końcowych Analiza statyczna kodu Extract Method Inline Method Rename Class/ Method/ Field Encapsulate Downcast Self Encapsulate Field Czym jest serwlet?
Refaktoryzacje trudne Weryfikacja warunków wstępnych i końcowych Testowanie Move Method/Field Decompose Conditional Replace Conditional with Polymorphism Introduce Null Object Czym jest serwlet?
Testy regresyjne PRZED ZMIANĄ PO ZMIANIE void doSth() void doSth()
Przykład: Decompose Conditional int liczba = uczen.getPrzedmioty(); if (liczba == 0) { // nie ma przedmiotów } else if (liczba = 1) { // jeden przedmiot } else { // Wiele przedmiotów } int liczba = uczen.getPrzedmioty(); if (liczba == 0) { zeroPrzedmiotów(); } else if (liczba = 1) { jedenPrzedmiot(); } else { wielePrzedmiotów(); } Wyłącz sam warunek do osobnej metody Wyłącz każdą gałąź warunku do osobnej metody, korzystając z Extract Method Czym jest serwlet? Krótszy kod warunkowy Niezależna obsługa każdej gałęzi warunku Możliwość pokrywania w podklasach
Przykład: Replace Conditional with Polymorphism Uczen uczen = Uczen.forLiczba(liczba); uczen.obsłuż(); Uczen + obsłuż() Uczen0 Uczen1 UczenN int liczba = uczen.getLiczbaPrzedmiotów(); if (liczba == 0) { // nie ma przedmiotów } else if (liczba = 1) { // jeden przedmiot } else { // Wiele przedmiotów } Skompiluj i przetestuj Powtarzaj dla każdej podklasy, aż wszystkie gałęzie warunku zostaną zastąpione Uczyń metodę w nadklasie abstrakcyjną Zastąp gałąź odwołaniem do metody utworzonego obiektu Skompiluj i przetestuj Wybierz podklasę; utwórz w niej metodę i skopiuj do niej ciało jednej z gałęzi warunku Utwórz podklasy rozważanego obiektu Czym jest serwlet? Pełna elastyczność Prosty, czytelny kod Łatwa skalowalność
Kiedy refaktoryzować? Przy naglących terminach Przedwczesne definiowanie interfejsów Niestabliny, bałaganiarski kod Zasada trzech razy Przy dodawaniu nowych funkcji Usuwając błąd Podczas przeglądu kodu Niedokończona refaktoryzacja to zadłużenie, które trzeba kiedyś spłacić Ward Cunningham
Nareszcie! Podsumowanie Refaktoryzacja pomaga usuwać przykre zapachy w kodzie Łatwiejsza pielęgnacja kodu Elegantsze rozwiązania, prostszy projekt Wspomaganie ze strony IDE Rola testów regresyjnych
Pytania? ?