Title: Refaktorisanje
1Refaktorisanje
- Mentor Dragan Bojic
- AutorMiloš Gligoric
2Sadržaj
- Å ta je refaktorisanje ?
- Zašto treba refaktorisati ?
- Kada treba vršiti refaktorisanje ?
- Kako sprovesti refaktorisanje ?
- Katalog refaktorisanja
- Alati za refaktorisanje
3Å 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 ne menja ponašanje
sistema ali povecava neke ne funkcionalne
kvalitete jednostavnost, fleksibilnost, jasnocu
...
4Motivacija
- Stara inženjerska izreka dok radi ne diraj ga.
- Postaje znatno teže ukoliko treba sprovesti
promene sistema
5Motivacija
- Estetsko pitanje nije jedini razlog negodovanja
neurednog koda - Kompajler ne mari da li je kod neuredan ili ne
- Kada je potrebno sprovesti promene sistema u taj
proces ukljuceni su i ljudi
6Motivacija
- Neuredan kod i loše dizajniran sistem otežavaju
promene - Teško je pronaci 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
7Motivacija Enkapsuliranje polja
- Transformacije koje se sprovode
- Kreiranje javnog get metoda koji vraca vrednost
polja - Kreiranje javnog set metoda koji postavlja
vrednost polja na vrednost prosledjenog parametra - Zamenjuje sva citanja polja sa pozivom get metoda
- Zamenjuje sve dodele vrednosti nekom polju sa set
metodom - Menja modifikator pristupa polju na private
8Motivacija Enkapsuliranje polja
- // 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
-
9Motivacija katalog refaktorisanja
- Promena imena (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) - ...
10Sadržaj
- Å ta je refaktorisanje ?
- Zašto treba refaktorisati ?
- Kada treba vršiti refaktorisanje ?
- Kako sprovesti refaktorisanje ?
- Katalog refaktorisanja
- Alati za refaktorisanje
11Zašto vršiti refaktorisanje ?
- Popravlja dizajn softvera
- Kratkorocni ciljevi kvare dizajn
- Eliminisanje dupliranog koda
- Cini softver razumljivijim
- Naknadna promena koda
- Razumevanje nepoznatog koda
12Zašto vršiti refaktorisanje ?
- Pomaže u nalaženju grešaka
- Razumevanje dovodi do pronalaženja grešaka
- Omogucava brže pisanje koda
- Dobra dizajn omogucava brz razvoj softvera
- Vreme je posveceno novim funkcionalnostima
- Refaktorisanje nije svemoguce!
13Sadržaj
- Å ta je refaktorisanje ?
- Zašto treba refaktorisati ?
- Kada treba vršiti refaktorisanje ?
- Kako sprovesti refaktorisanje ?
- Katalog refaktorisanja
- Alati za refaktorisanje
14Kada 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
15Kada 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
16Kada NE treba vršiti refaktorisanje ?
- Kada je bolje poceti od pocetka
- Kod pun grešaka
- Kada istice rok
- Dobici bi stigli po isteku roka
17Sadržaj
- Å ta je refaktorisanje ?
- Zašto treba refaktorisati ?
- Kada treba vršiti refaktorisanje ?
- Kako sprovesti refaktorisanje ?
- Katalog refaktorisanja
- Alati za refaktorisanje
18Kako zapoceti 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
19Sprovodjenje refaktorisanja
- Refaktorisanje menja program malim koracima. Ako
nacinite grešku, lako cete je pronaci - Rimat refaktorisanja testiranje, male izmene,
testiranje, male izmene, testiranje, male izmene.
Ovaj ritam omogucava brzo i sigurno refaktorisanje
20Å ta treba refaktorisati ?
- Beck Identifikovati bed smells u kodu
- konkretne strukture u kodu koje dozivaju
(ponekad zapomažu), pružajuci mogucnost za
refaktorisanje
21Å ta treba refaktorisati ?
- Ponovljeni kod
- Izdvajanje metoda, Povlacenje metoda naviše,
Pravljenje Å¡ablonskog metoda, Zamena algoritma - Dugacak metod
- Izdvajanje metoda, Zamena primitivnih
promenljivih upitom, Uvodjenje parametarskog
objekta, Ocuvanje celovitosti objekta
22Å ta treba refaktorisati ?
- Velika klasa
- Izdvajanje klase, Izdvajanje potklase
- Dugacka lista parametara
- Zamena parametra metodom, Uvodjenje parametarskog
objekta - Lenja klasa
- Rušenje hijerarhije, Umetanje klasa
- ...
23Sadržaj
- Å ta je refaktorisanje ?
- Zašto treba refaktorisati ?
- Kada treba vršiti refaktorisanje ?
- Kako sprovesti refaktorisanje ?
- Katalog refaktorisanja
- Alati za refaktorisanje
24Katalog refaktorisanja
- Format navodjenja refaktorisanjaFowler
- Ime refaktorisanja
- Situacija u kojoj to refaktorisanje služi
- Motivacija (zašto treba obaviti refaktorisanje)
- Mehanizam (kako se refaktorisanje sprovodi)
- Primer
- Koristice se delovi gornjeg formata
25Izdvajanje metoda
- Izdvajanje metoda (Extract Method)
- Postoji fragment koda koji se može grupisati
- Pretvoriti taj deo u metod cije ime objašnjava
namenu metoda (ne kako metod radi!)
26Izdvajanje metoda
- 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)
-
27Izdvajanje 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
28Izdvajanje 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
29Izdvajanje metoda (mehanizam)
- Lokalne promenljive proslediti odredišnom metodu
u vidu parametara koji se citaju iz izvornog koda - Zameniti izdvojeni kod u izvornom metodu pozivom
lokalnim promenljivim - Prevesti i testirati
30Zamena privremene promenljive upitom
- Zamena privremene promenljive upitom (Replace
Temp With Query) - Privremena promenljiva se koristi za cuvanje
rezultata nekog izraza - Izdvojiti izraz u metodu. Zameniti izrazom sve
refenece na tu privremenu promenljivu
31- double basePrice _quantity _itemPrice
- if (basePrice gt 1000)
- return basePrice 0.95
- else
- return basePrice 0.98
- if (basePrice() gt 1000)
- return basePrice() 0.95
- else
- return basePrice() 0.98
- ...
- double basePrice()
- return _quantity _itemPrice
32Razdvajanje 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
33- 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)
34Zamena metoda objektom metoda
- Zamena metoda objektom metoda (Replace Method
With Method Object) - Uocava 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
35- class Order...
- double price()
- double primaryBasePrice
- double secondaryBasePrice
- double tertiaryBasePrice
- // long computation
- ...
-
36Premeštanje metoda
- Premeštanje metoda (Move Method)
- Metod koristi više odlika neke klase u kojoj nije
definisan - Napraviti novi metod sa slicnim osnovnim delom u
klasi koju najviše koristi
37(No Transcript)
38Izdvajanje klase
- Izdvajanje klase (Extract Class)
- Imate klasu koja obavlja posao koji bi trebalo da
obavljaju dve klase - Napravite novu klasu i premestite odgovarajuca
polja i metode iz stare klase u novu
39(No Transcript)
40Zamena 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
41(No Transcript)
42Sadržaj
- Å ta je refaktorisanje ?
- Zašto treba refaktorisati ?
- Kada treba vršiti refaktorisanje ?
- Kako sprovesti refaktorisanje ?
- Katalog refaktorisanja
- Alati za refaktorisanje
43Alati za refaktorisanje
- Postoje za vecinu popularnih OO programskih
jezika - Java
- Xrefactory, RefactorIT, jFactor, IntelliJ IDEA,
Eclipse - C
- CppRefactory, Xrefactory C
- C Refactoring Tool, C Refactory
- Delphi
- Modelmaker Tool, Castalia
-
44Alati za refaktorisanje
- Postoje za vecinu popularnih razvojnih okruženja
(IDE) - NetBeans (RefactorIT)
- Eclipse (built-in)
- Borland JBuilder (RefactorIT)
- VisualStudio .NET (C Refactory)
- ...
45Alati za refaktorisanjeEclipse
46Alati za refaktorisanjeNetBeans
47Alati za refaktorisanjeMS Visual 2005
48Alati za refaktorisanjePouzdanost
- Koliko su alati za refaktorisanje zaista pouzdani
?
49Alati 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
50Bug 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