Refaktoryzacja „Any fool can write a code that computer understands. Good programers write code that human can understand” – Martin Fowler
Refaktoryzacja – podstawowe zasady Zmiana wewnętrznej struktury kodu Brak zmiany zachowania Składa się z serii niewielkich transformacji Czyści kod minimalizują ryzyko wstawienia bug-a
Po co ? Aby ułatwić wprowadzanie zmian Aby poprawić konstrukcję Aby lepiej poznać kod Aby praca z kodem była przyjemna
Zapachy kodu Duplicated code Long methods Large class Long parameter List Feature Envy Switch Statements Lazy Class Comments i parę innych
Refaktoring Zidentyfikuj problem Napisz testy Przeprowadź refaktoring Sprawdź działanie
Metody Extract method void printOwing(double amount) { printBanner(); //print details System.out.println ("name:" + _name); System.out.println ("amount" + amount); } void printOwing(double amount) { printBanner(); printDetails(amount); } void printDetails (double amount) { System.out.println ("name:" + _name); System.out.println ("amount" + amount) }
Metody Inline Method int getRating() { return (moreThanFiveLateDeliveries()) ? 2 : 1; } boolean moreThanFiveLateDeliveries() { return _numberOfLateDeliveries > 5; } int getRating() { return (_numberOfLateDeliveries > 5) ? 2 : 1; }
Metody Replace Temp with Query double basePrice = _quantity * _itemPrice; if (basePrice > 1000) return basePrice * 0.95; else return basePrice * 0.98; if (basePrice() > 1000) return basePrice() * 0.95; else return basePrice() * 0.98;... double basePrice() { return _quantity * _itemPrice; }
Metody cd. Inline Temp Introduce Explaining Variable Remove Assignments to Parameters Replace Method with Method Object Substitute Algorithm
Pomiędzy obiektami Move method
Pomiędzy obiektami Extract Class
Pomiędzy obiektami Hide Delegate
Pomiędzy obiektami Move field Inline Class Remove Middle Man – odwrotność Hide Delegate Introduce Foreign Method Introduce Local Extension
Organizacja danych Replace Data with Object
Organizacja danych Replace Array with Object String[] row = new String[3]; row [0] = "Liverpool"; row [1] = "15"; Performance row = new Performance(); row.setName("Liverpool"); row.setWins("15");
Organizacja danych Duplicate Observed Data
Organizacja danych Encapsulate Collection
Organizacja danych Replace Type Code with Strategy
Organizacja danych Self Encapsulate Field Change Value to Reference Change Reference To Value Replace Magic Number with Symbolic Constant Encapsulate Field Replace Type Code with Class
Upraszczanie wyrażeń Consolidate Duplicate Conditional Fragment if (isSpecialDeal()) { total = price * 0.95; send(); } else { total = price * 0.98; send(); } if (isSpecialDeal()) total = price * 0.95; else total = price * 0.98; send();
Upraszczanie wyrażeń Replace Conditional With Polymorphism double getSpeed() { switch (_type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts; case NORWEGIAN_BLUE: return (_isNailed) ? 0 : getBaseSpeed(_voltage); } throw new RuntimeException ("Should be unreachable"); }
Upraszczanie Wyrażeń Inroduce Null Object if (customer == null) plan = BillingPlan.basic(); else plan = customer.getPlan();
Upraszczenie wyrażeń Introduce Assertion Remove Control Flag Consolidate Conditional Expression Decompose Conditional
Uproszczenie wywołań Rename Method
Uproszczenie wywołań Parametrize Method
Upraszczanie wywołań Add Parameter Remove Parameter Replace Parameter with Explicit Method Replace Parameter with Method Replace Error Code with Exception Replace Exception With Test
Dziedziczenie Pull Up Field
Dziedziczenie Push Down Method
Dziedziczenie Extract Superclass
Dziedziczenie Form Template Method
Dziedziczenie Pull Up Method Pull Up Constructor Body Extract Subclass Push Down Field Extract Interface Collapse Hierarchy Replace Inheritance with Delegation
Refaktoring baz danych Ewolucja schematu Zapachy bazodanowe Kolumny i tabele z więcej niż jednym przeznaczeniem Nadmiarowe dane Zbyt dużo kolumn „Inteligentne” kolumy