Egy szoftver fejlesztése során elkerülhetetlen, hogy idÅ‘vel ne keletkezzenek úgynevezett technical debt-ek, ami egy igen találó kifejezés. Ez szó szerint fordÃtva egy technikai adósság, ami a való életbeli adóssághoz hasonlóan minél késÅ‘bb kerül megfizetésre, annál többe fog nekünk kerülni.
Technical debt-ek esetén ezeket nem anyagilag fogjuk elszenvedni, hanem egy sokkal értékesebb erÅ‘forrásban: idÅ‘ben. Minél több technical debt-el rendelkezik egy szoftver, annál több idÅ‘t fog igénybe venni egy újabb funkció hozzáadása, vagy egy esetleges hiba javÃtása.
De milyen külső tényezők befolyásolják ezeket az adósságokat? Technical debt keletkezhet szimplán azért, mert fejlesztés közben megváltozik vagy nem jól tisztázott a követelmény. Az is előfordulhat, hogy sürget a határidő. Ezek mind nem túl szép megoldásokhoz vezetnek a kódban. Ezeknek a nem szép megoldásoknak egy speciális kategóriája a workaround. A workaround egy olyan megoldás, ami a szoftver architektúrájába nem igen illeszkedik.
De mit kezdhetünk az adósságainkkal? Egy darabig élhetünk velük. Ignorálhatjuk is őket, mivel a bankokkal és a jogszabályokkal ellentétben ezek megfizetésére nincs jogi alap. Viszont, ha az ignorálás mellett döntünk, akkor előbb-utóbb több adósság fog keletkezni, ami hosszabb vagy rövidebb távon a projekt bukását eredményezheti.
Természetesen dönthetünk amellett is, hogy megfizetjük az adósságainkat. Ennek a folyamata a refaktorálás.
A refaktorálás a kód átalakÃtásának folyamata úgy, hogy közben a kód viselkedése nem változik, csak a struktúrája. Refaktorálni lehet tesztek nélkül is, csak nem érdemes, mivel ebben az esetben nem tudjuk biztosÃtani azt, hogy a kód viselkedése ne változzon. Ez számos elÅ‘nnyel járhat:
- JavÃthatjuk a komponens tervét és minÅ‘ségét
- Csökkenthetjük vele a technical debt-ek mennyiségét
- Felfedezhetünk és kijavÃthatunk eddig észre nem vett hibákat
- MegkönnyÃthetjük újabb funkciók hozzáadását
- SegÃti a komponensek belsÅ‘ működésének megértését
Ez jól hangzik, de tudni kell, hogy hol a határ. Olyan kód nem létezik, amit nem lehetne jobbá tenni refaktorálással, ezért fontos tudni, hogy mikor kell abbahagyni: sose refaktoráljunk csak azért, mert refaktorálni akarunk. A refaktorálásnak mindig egy minÅ‘ségi célt kell megvalósÃtania.
Ilyen minőségi cél lehet:
- Duplikált vagy hasonló osztályok egybevonása
- Hosszú metódusok több, kisebb olvashatóra bontása
- Túl sok argumentummal rendelkező metódusok átdogozása
- Halott kód eltávolÃtása
- Sorok számának csökkentése
- Blokk mélység csökkentése
- Ciklomatikus komplexitás.
A ciklomatikus komplexitás egy szoftvermetrika. A komplexitás számÃtása a gráfelméletre alapul. Értéke az alábbi módon határozható meg: M = E − N + 2P, ahol:
- E: A gráf éleinek száma
- N: A gráfban lévő csúcsok száma
- P: Az összefüggő komponensek száma
A gráfot az adott függvényben lévÅ‘ utasÃtások alkotják, él akkor van 2 utasÃtás között, ha az egyik után a másik azonnal végrehajtódhat, Ãgy a metrika közvetlenül számolja a lineárisan független útvonalakat a forráskódon keresztül.
Szerencsére ezt nem kell nekünk manuálisan számÃtani. A Visual Studio az Analyze menüpont alatt tartalmaz egy Calculate Code Metrics menüpontot, amivel az egész solution-re vagy projektre kiszámÃttathatjuk ezt.
A számÃtás a projekt méretétÅ‘l függÅ‘en eltarthat egy ideig. A számÃtás végeztével megkapjuk ciklomatikus komplexitást és egy számolt karbantarthatósági indexet, illetve a programunk azon sorainak a számát, amik végrehajtható utasÃtásokat tartalmaznak.
Mikor ne refaktoráljunk?
A refaktorálás veszélyes tud lenni kellÅ‘ körültekintés nélkül. Legjobb szándékunkkal is elÅ‘fordulhat, hogy a refaktorálás nem várt új hibákat vezet be a rendszerbe. Éppen ezért fontos, hogy mielÅ‘tt belekezdünk, legyen elegendÅ‘ egységteszttel lefedve a komponens, hogy átalakÃtás után is tudjuk, hogy jól működik.
Akkor sem ajánlott refaktorálni, ha éppen funkciót fejlesztünk. Ennek az oka az, hogy funkció fejlesztés közben másként gondolkodunk, mint amikor refaktorálunk. A kettő keverése pedig ismételten csak nem várt hibák megjelenéséhez vezethet.
Sajnos vannak azok a szoftverek, amelyeken már a refaktorálás sem segÃt. Ebben az esetben érdemes elgondolkodni a komponens újratervezésén. A komponens újratervezésének oka lehet a szoftver architektúrájának változása vagy a komponensben lévÅ‘ sok hiba. Egy vagy több komponens újratervezése költséges, de megmenthet egy szoftvert.
Radikálisabb és költségesebb megoldás a teljes szoftver újraÃrása, ami felbecsülhetetlen költséggel járhat, valamint egy bejáratott szoftvertermék esetén a piaci pozÃciót negatÃvan is befolyásolhatja. Éppen ezért az újraÃrás csak az utolsó utáni lehetÅ‘ségnek merüljön fel.