200 likes | 324 Views
Refaktoryzacja czyli odświeżanie kodu. Łukasz Olek Dzięki uprzejmości Bart ka Walte ra. 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.
E N D
Refaktoryzacjaczyli 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
Przykre zapachy If it stinks, change it babcia Kenta Beckao 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()
void oblicz () { // oblicz X // oblicz Y wyswietl(X, Y); // zapisz X // zapisz Y } void obliczINapisz() { // oblicz X // oblicz Y ... // wyświetl X // wyświetl Y ... // zapisz X // zapisz Y } void wyswietl(X,Y) { // wyświetl X // wyświetl Y } Przykłady refaktoryzacji Extract Method • 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...
Refaktoryzacje proste... • Weryfikacja warunków wstępnych i końcowych • Analiza statyczna kodu void doSth() void doSth() Jeżeli przed....Jeżeli przed.... Jeżeli po....Jeżeli po....
void doSth() void doSth() 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
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
Refaktoryzacje trudne • Weryfikacja warunków wstępnych i końcowych • Testowanie • Move Method/Field • Decompose Conditional • Replace Conditional with Polymorphism • Introduce Null Object
Testy regresyjne PRZED ZMIANĄ PO ZMIANIE void doSth() void doSth() void doSth()
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();} • Krótszy kod warunkowy • Niezależna obsługa każdej gałęzi warunku • Możliwość pokrywania w podklasach Przykład: Decompose Conditional Wyłącz sam warunek do osobnej metody Wyłącz każdą gałąź warunku do osobnej metody, korzystając z Extract Method
Uczen uczen = Uczen.forLiczba(liczba);uczen.obsłuż(); int liczba = uczen.getLiczbaPrzedmiotów(); if (liczba == 0) {// nie ma przedmiotów} else if (liczba = 1) {// jeden przedmiot} else {// Wiele przedmiotów} Uczen + obsłuż() Uczen0 Uczen1 UczenN + obsłuż() + obsłuż() + obsłuż() • Pełna elastyczność • Prosty, czytelny kod • Łatwa skalowalność Przykład: Replace Conditional with Polymorphism Skompiluj i przetestuj Skompiluj i przetestuj Zastąp gałąź odwołaniem do metody utworzonego obiektu Utwórz podklasy rozważanego obiektu Powtarzaj dla każdej podklasy, aż wszystkie gałęzie warunku zostaną zastąpione Wybierz podklasę; utwórz w niej metodę i skopiuj do niej ciało jednej z gałęzi warunku Uczyń metodę w nadklasie abstrakcyjną
Niedokończona refaktoryzacja to zadłużenie, które trzeba kiedyś spłacić Ward Cunningham 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
Podsumowanie Nareszcie! • 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? ?