500 likes | 709 Views
Refaktorisanje. Mentor: D r agan Boji ć Autor: Miloš Gligorić. Sadržaj. Šta je refaktorisanje ? Zašto treba refaktorisati ? Kada treba vršiti refaktorisanje ? Kako sprovesti refaktorisanje ? Katalog refaktorisanja Alati za refaktorisanje. Šta je refaktorisanje ?.
E N D
Refaktorisanje Mentor: Dragan Bojić Autor:Miloš Gligorić
Sadržaj • Šta je refaktorisanje ? • Zašto treba refaktorisati ? • Kada treba vršiti refaktorisanje ? • Kako sprovesti refaktorisanje ? • Katalog refaktorisanja • Alati za refaktorisanje
Šta je refaktorisanje ? • Proces promene softverskog sistema • Ne dovodi do promene spoljnog ponašanja koda • Poboljšava unutrašnju strukturu • Neke od definicija: • [Fowler] Refaktorisanje je izmena interne strukture softvera da bi bio lakši za razumevanje i jednostavniji za modifikovanje, a bez vidljivih promena njegovog ponašanja. • [Beck] Promena sistema koja nemenja ponašanje sistema ali povećava neke ne funkcionalne kvalitete: jednostavnost, fleksibilnost, jasnoću ...
Motivacija • Stara inženjerska izreka: “dok radi nediraj ga.” • Postaje znatno teže ukoliko treba sprovesti promene sistema
Motivacija • Estetsko pitanje nije jedini razlog negodovanja neurednog koda • Kompajler nemari da li je kod neuredan ili ne • Kada je potrebno sprovesti promene sistema u taj proces uključeni su i ljudi
Motivacija • Neuredan kod i loše dizajniran sistem otežavaju promene • Teško je pronaći mesta koja je potrebno menjati • Teško je prepoznati šta treba menjati • Kada je potrebno dodati nove odlike sistemu a kod nije strukturiran kako bi prihvatio nove promene • refaktorisati program kako bi se olakšalo dodavanje novih odlika • zatim dodati nove odlike
Motivacija – Enkapsuliranje polja • Transformacijekoje se sprovode • Kreiranje javnog get metoda koji vraća vrednost polja • Kreiranje javnog set metoda koji postavlja vrednost polja na vrednost prosledjenog parametra • Zamenjuje sva čitanja polja sa pozivom get metoda • Zamenjuje sve dodele vrednosti nekom polju sa set metodom • Menja modifikator pristupa polju na private
// pre refaktorisanja class A { public int f; void m(int i) { f = i * f; } } // nakon refaktorisanja class A { private int f; void m(int i) { setF(i * getF()); } public int getF() { return this.f; } public void setF(int f) { this.f = f; } } Motivacija –Enkapsuliranje polja
Motivacija – katalogrefaktorisanja • Promenaimena (Rename): promena imena metode, polja, klase • Enkapsuliranje polja (Encapsulate Field): zamena svih referenci polja sa metodama za pristup • Pomeranje polja na dole: pomeranje polja iz superklase u sve podklase • Promena potpisa: promena potpisa metode promenom povratnog tipa, dodavanjem(Add Parameter) ili uklanjajem parametara(Remove Parameter) • ...
Sadržaj • Šta je refaktorisanje ? • Zašto treba refaktorisati ? • Kada treba vršiti refaktorisanje ? • Kako sprovesti refaktorisanje ? • Katalog refaktorisanja • Alati za refaktorisanje
Zašto vršiti refaktorisanje ? • Popravlja dizajn softvera • Kratkoročni ciljevi kvare dizajn • Eliminisanje dupliranog koda • Čini softver razumljivijim • Naknadna promena koda • Razumevanje nepoznatog koda
Zašto vršiti refaktorisanje ? • Pomaže u nalaženju grešaka • Razumevanje dovodi do pronalaženja grešaka • Omogućava brže pisanje koda • Dobra dizajn omogućava brz razvoj softvera • Vreme je posvećeno novim funkcionalnostima • Refaktorisanje nije svemoguće!
Sadržaj • Šta je refaktorisanje ? • Zašto treba refaktorisati ? • Kada treba vršiti refaktorisanje ? • Kako sprovesti refaktorisanje ? • Katalog refaktorisanja • Alati za refaktorisanje
Kada treba vršiti refaktorisanje ? • Ne treba definisati termine refaktorisanja • Prilikom dodavanja funkcionalnosti • U cilju razumevanja koda koji se modifikuje • Promena dizajna za jednostavno dodavanje funkcionalnosti
Kada treba vršiti refaktorisanje ? • Tokom otklanjanja grešaka • Kod postaje razumljiviji • Greška može uputiti na potrebu za refaktorisanjem • Tokom pregledanja koda • Dobijanje konkretnijih rezultata
Kada NE treba vršiti refaktorisanje ? • Kada je bolje početi od početka • Kod pun grešaka • Kada ističe rok • Dobici bi stigli po isteku roka
Sadržaj • Šta je refaktorisanje ? • Zašto treba refaktorisati ? • Kada treba vršiti refaktorisanje ? • Kako sprovesti refaktorisanje ? • Katalog refaktorisanja • Alati za refaktorisanje
Kako započeti refaktorisanje ? • Kreiranje solidnog skupa testova za deo koda koji se želi refaktorisati! • Kreiranje testova upotrebom xUnit alata • Grupisanje testova • Regresivno testiranje • Automatska provera ishoda testiranja • Pisanje testova je vredno truda • Daju samopouzdanju za sprovodjenje izmena
Sprovodjenje refaktorisanja • Refaktorisanje menja program malim koracima. Ako načinite grešku, lako ćete je pronaći • Rimat refaktorisanja: testiranje, male izmene, testiranje, male izmene, testiranje, male izmene. Ovaj ritam omogućava brzo i sigurno refaktorisanje
Šta treba refaktorisati ? • [Beck] Identifikovati “bed smells” u kodu • “konkretne strukture u kodu koje dozivaju (ponekad zapomažu), pružajući mogućnost za refaktorisanje”
Šta treba refaktorisati ? • Ponovljeni kod • Izdvajanje metoda, Povlačenje metoda naviše, Pravljenje šablonskog metoda, Zamena algoritma • Dugačak metod • Izdvajanje metoda, Zamena primitivnih promenljivih upitom, Uvodjenje parametarskog objekta, Očuvanje celovitosti objekta
Šta treba refaktorisati ? • Velika klasa • Izdvajanje klase, Izdvajanje potklase • Dugačka lista parametara • Zamena parametra metodom, Uvodjenje parametarskog objekta • Lenja klasa • Rušenje hijerarhije, Umetanje klasa • ...
Sadržaj • Šta je refaktorisanje ? • Zašto treba refaktorisati ? • Kada treba vršiti refaktorisanje ? • Kako sprovesti refaktorisanje ? • Katalog refaktorisanja • Alati za refaktorisanje
Katalogrefaktorisanja • Format navodjenja refaktorisanja[Fowler] • Ime refaktorisanja • Situacija u kojoj to refaktorisanje služi • Motivacija (zašto treba obaviti refaktorisanje) • Mehanizam (kako se refaktorisanje sprovodi) • Primer • Koristiće se delovi gornjeg formata
Izdvajanje metoda • Izdvajanje metoda (Extract Method) • Postoji fragment koda koji se može grupisati • Pretvoriti taj deo u metod čije ime objašnjava namenu metoda (nekakometod radi!)
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); } Izdvajanje metoda
Izdvajanje metoda (mehanizam) • Kreirati novi metod i izvršiti imenovanje u skladu sa akcijom koju metod sprovodi • Iskopirati izdvojeni kod iz izvornog metoda u novokreirani metod • Potražiti u izvornom kodu reference na promenljive koje su lokalne u izvornom kodu. To su lokalne promenljive i parametri
Izdvajanje metoda (mehanizam) • Ukoliko se neka privremena promenljiva upotrebljava samo u izdvojenom kodu. Ako je tako, deklarisati je u odredišnom kodu • Proveriti da li se u izdvojenom kodu vrši izmena lokalne promeljive polaznog metoda
Izdvajanje metoda (mehanizam) • Lokalne promenljive proslediti odredišnom metodu u vidu parametara koji se čitaju iz izvornog koda • Zameniti izdvojeni kod u izvornom metodu pozivom lokalnim promenljivim • Prevesti i testirati
Zamena privremene promenljive upitom • Zamena privremene promenljive upitom (Replace Temp With Query) • Privremena promenljiva se koristi za čuvanje rezultata nekog izraza • Izdvojiti izraz u metodu. Zameniti izrazom sve refenece na tu privremenu promenljivu
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; }
Razdvajanje privremene promenljive • Razdvajanje privremene promenljive (Split Temporary Variable) • Postoji privremena promenljiva kojoj je vrednost dodeljena više puta, ali nije u petlji niti se koristi za skupljanje rezultata • Kreirati posebnu privremenu promenljivu za svaku dodelu
double temp = 2 * (_height + _width); System.out.println (temp); temp = _height * _width; System.out.println (temp); final double perimeter = 2 * (_height + _width); System.out.println (perimeter); final double area = _height * _width; System.out.println (area);
Zamena metoda objektom metoda • Zamena metoda objektom metoda (Replace Method With Method Object) • Uočava se dug metod koji koristi lokalne promenljive tako da ne možete da primenite Izdvajanje Metoda • Pretvorite metod u zaseban objekat tako da sve lokalne promenljive postanu polja tog objekta. Onda metod možete razložiti na druge metode istog objekta
class Order... double price() { double primaryBasePrice; double secondaryBasePrice; double tertiaryBasePrice; // long computation; ... }
Premeštanje metoda • Premeštanje metoda (Move Method) • Metod koristi više odlika neke klase u kojoj nije definisan • Napraviti novi metod sa sličnim osnovnim delom u klasi koju najviše koristi
Izdvajanje klase • Izdvajanje klase (Extract Class) • Imate klasu koja obavlja posao koji bi trebalo da obavljaju dve klase • Napravite novu klasu i premestite odgovarajuća polja i metode iz stare klase u novu
Zamena prostog podatka objektom • Zamena prostog podatka objektom (Replace Data Value with Object) • Imate stavku podatka kojoj su potrebni dodatni podaci ili ponašanje • Pretvorite stavku podatka u objekat
Sadržaj • Šta je refaktorisanje ? • Zašto treba refaktorisati ? • Kada treba vršiti refaktorisanje ? • Kako sprovesti refaktorisanje ? • Katalog refaktorisanja • Alati za refaktorisanje
Alati za refaktorisanje • Postoje za većinu popularnih OO programskih jezika • Java • Xrefactory, RefactorIT, jFactor, IntelliJ IDEA, Eclipse • C++ • CppRefactory, Xrefactory – C# • C# Refactoring Tool, C# Refactory • Delphi • Modelmaker Tool, Castalia • …
Alati za refaktorisanje • Postoje za većinu popularnih razvojnih okruženja (IDE) • NetBeans (RefactorIT) • Eclipse (built-in) • Borland JBuilder (RefactorIT) • VisualStudio .NET (C# Refactory) • ...
Alati za refaktorisanjePouzdanost • Koliko su alati za refaktorisanje zaista pouzdani ?
Alati za refaktorisanjePouzdanost • Istraživanja na University of Illinois at Urbana-Champaign • Tokom 2007 identifikovano 45 bagova • 21 bug-a u Eclipse-u • 24 bug-a u NetBeans-u
// pre refaktorisanja class A { int f; void m() { (new A().f) = 0; } } // nakon refaktorisanja class A { private int f; void m() { (new A().f) = 0; } … getF … … setF … } Bug u NetBeans-u