Thursday, 17 July 2014

Code Smells - Change Preventers

Ova klasa code smell-ova se odnosi na one koji otežavaju izmene u kodu i koji afektiraju više delova koda i sistema. Stoga, kada je potrebno uraditi izmenu koda, koja se tiče jedne semantičke celine, potrebno je izmeniti kod na više mesta.
Ovi code smell-ovi obično znače i da postoji jaka uvezanost (tight coupling) delova sistema, što znači da je prilično teško, ako ne i nemoguće, zameniti deo sistema pošto je svaki deo jako uvezan sa ostalim delovima sistema.
Takođe, ovi code smell-ovi često ukazuju da postoji slaba/nejasna raspodela odgovornosti (poor separation of concerns), kako među komponentama, tako i među klasama. U ovom slučaju, narušen je jedan od osnovnih principa objektno orijentisanog dizajna, a to je Single Responsibility Principle (SRP). Ovaj princip se odnosi na stepen kohezije klase i kaže da svaka klasa treba da ima jednu i samo jednu odgovornost i da ta odgovornost treba da bude u potpunosti enkapsulirana u toj klasi, pri čemu se odgovornost definiše kao razlog za izmenu.

Konkretni code smell-ovi koji potpadaju pod change preventers grupu su:
  • Divergent change
  • Shotgun surgery
  • Parallel inheritance hierarchy
  • Inconsistent abstraction level i
  • Conditional complexity

Divergent change

Ovaj code smell se odnosi na situaciju kada se klasa, najčešće, menja na dva ili više različita načina ili zbog dva ili više razloga, što predstavlja narušavanje SRP-a.

Shotgun surgery


Shotgun surgery podrazumeva situaciju koja se manifestuje tako da prilikom rešavanja nekog bug-a (ili dodavanja nove f-nalnosti), je potrebno izmeniti kod na dosta mesta, gde je lako zaboraviti neku izmenu. Ova situacija ukazuje na grešku u dizajnu, jer jedna izmena afektuje više klasa. Idealno, trebalo bi da postoji jedan-na-jedan veza između izmene i klase.

Parallel inheritance hierarchy

Ovo je specijalni slučaj shotgun surgery code smell-a, gde dodavanja klase u jednu hijerarhiju zahteva dodavanje klase u paralelnu hijerarhiju(e).


Obično se ovaj problem zaobilazi koristeći Move Method refaktorisanje, gde se metode iz klasa referencirane paralelne hijerarhije, prebacuju u korespodentne klase u inicijalnoj hijerarhiji.


Ovo, sa druge strane, može narušiti SRP, pošto se odgovornosti i logika iz jedne klase prebacuju u drugu klasu, u kojoj ne bi trebalo da stoje.
Druga solucija, je da se sve metode referencirane hijerarhije sažmu u jednu klasu. Ovo je prihvatljivo ako broj klasa u referenciranoj hijerarhiji nije prevelik.


Inconsistent abstraction level

Interface klase treba da pruža konzistentan nivo apstrakcije. Ovaj nivo konzistencije opada sa dodavanjem novih, dodatnih metoda klasi. Inconsistent abstraction level code smell se dešava na nivou klasa, gde public metode moraju imati kohezivan set metoda (refactoring: move method), a takođe se dešava i na nivou metode, gde implementacija metode mora biti na nivou apstrakcije jednom ispod onog koji ime metode implicira (refactoring: extract method).

Cyclomatic complexity

Cyclomatic complexity (ili conditional complexity) predstavlja softversku metriku koja ukazuje na meru kompleksnosti programa. Metrika je razvijena od strane Thomas J. McCabe, Sr i vrednost, na koju ukazuje, se često naziva McCabe index. McCabe index date metode predstavlja broj linearno nezavisnih putanja izvršavanja u okviru metode. Što je veći broj linearno nezavisnih putanja, to znači da je metoda kompleksnija, teža za razumevanje, održavanje i samim tim predstavlja metodu kandidata za refaktorisanja.
Prihvatljiv index je 1-5. Index 5-10 predstavlja metodu koja se može uzeti u razmatranje za refaktorisanje, dok index preko 10 ukazuje na metodu koja bi svakako trebalo da se uzme u razmatranje.
Takođe, potrebno je napomenuti da McCabe index za neke metode može biti visok zbog postojanja switch case naredbe unutar metode, koja drastično povećava broj linearno nezavisnih putanja izvršavanja. Ove metode, ako samo zbog switch case naredbe imaju visok McCabe index, nije neophodno uzeti u razmatranje, osim ako postoji mogućnost Replace conditional logic with Strategy refaktorisanja.

Koristan Visual Studio plugin, koji sadrži ovu softversku metriku, je CodeMaid i može se koristiti za potrebe merenja složenosti metoda neke klase (McCabe index).

Refaktorinzi koji se obično koriste kod cyclomatic complexity code smell-a su:


Dva mala saveta koja se mogu koristiti za poboljšanje čitljivosti koda su:

  • Extract boolean in if statement - radi čitljivosti, kompleksnu boolean logiku u if naredbi bi trebalo izdvojiti u posebnu metodu
  • Avoid negative conditionals (ItemIsValid vs ItemIsInvalid) - takođe zbog čitljivosti, naziv boolean metode koja se koristi u if naredbi treba biti afirmativan, umesto negativan

No comments:

Post a Comment