Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
Refactoring is a part of day-to-day programming.
Refactoring isn’t a special task that would show up in a project plan.
https://refactoring.com/
XP kirjan mukaan koodauksessa pitäisi keskittyä joka minuutti Businessarvon tuottamiseen Asiakkaalle (a.k.a PO), mihin päästään esim. käytännöillä Simple Design ja Refaktorointi
Refaktorointiin ei koskaan pidä pyytää Asiakkaalta lupaa JÄLKIKÄTEEN, vaan XP mukaan se on jokaisen tehtävän ENSIMMÄINEN toimenpide, jossa koodia refaktoroidaan niin että varsinainen Bisnesarvo/ominaisuus on helppo lisätä (ja testata)
Olen monesti kuullut senior-koodaajienkin ensin julistavan tehtävän valmiiksi, ja sitten pyytävän aikaa että ”voisin sitten vielä refaktoroida 3 päivää koodia paikoista x,y,z”. Asiakkaalle tämä kuulostaa erittäin huonolta, eli tätä kannattaa välttää sillä se saa koodaajan huonoon valoon Asiakkaan silmissä, sillä sen sijaan että koodaaja keskittyisi uuden taskin aloittamiseen, joka tuottaa bisneshyötyä niin koodaaja tuhlaakin asiakkaan kallista aikaa ja budjettia johonkin toissijaiseen ei-liiketoiminta-arvoa tuottavaan toimintaan. Siksi parempi strategia on siirtää tämä refaktorointivaihe aina koodauksen ALKUUN ja aina ENSIMMÄISEKSI tehtäväksi, koska sitä refaktorointiahan ei juuri nyt tarvita jos koodi toimii speksin mukaisesti.
Pahimmillaan ja yleisesti jälkikäteen tehtävä refaktorointi ja kaikkien muutosten tekeminen yleisesti johtaa siihen että sinne tulee vaan bugeja, eli Asiakkaan näkökulmastahan homma menee näin:
- Alun perin planningissa koodaajat sanoivat että tää on helppo homma, menee vain 3pv.
- No sitten asiakas odottaa kärsivällisesti 3pv x 5.2 (esim. viimeisin mittaus erään tiimin keskimääräinen edistyminen tällä hetkellä käytetyissä henkilötyöpäivissä / velocity eli valmistuneet taskit, mutta oon nähnyt paljon muitakin tehokkuuksia. Toimistollahan PHZ Full Stack:lla on odotusarvo tehdä alle 4 suhteessa koska pitäisi keskittyä Skillin lisäämiseen, Tiimityöhön eli pariohjelmointiin ja Laadun parantamiseen eli yksikkötestauksen opetteluun) eli 3+ viikkoa, niin sitten Asiakkaan iloksi koodaajat kertovat että ominaisuus on valmis
- Asiakas tekee hyväksyntätestausta, ja huomataan että speksit oli ymmärretty vähän väärin (tää johtuu siitä että Asiakas ei ollut tehnyt automaattisia Hyväksyntätestejä esim. Robot Framework:lla etukäteen) ja taski laitetaan takaisin 4. sprintin työlistalle
- Seuraavaksi n. 3vk päästä koodi on taas valmis, mitä Asiakas juhlii taas järjestämällä kakkukahvit koko tiimille
- Koodaaja sanoo, että voisi tehdä vielä viikoon refaktorointia, kun toisella puolella PO:n bisnessidosryhmät on raivoissaan viivästyksistä ja uhkaa irtisanoa sopimukset. Asiakkaasta ei tunnu hyvältä.
Refaktorointihan (XP:ssä Merciless Refactoring – Refactor Always When Needed and When Possible) tarkoittaa, että muutetaan koodin sisäistä rakennetta ilman että koodin ulkoinen käyttäytyminen muuttuu. Suomeksi tämä tarkoittaa sitä että, kun muutetaan koodin rakennetta niin speksit ei saa vaihtua, mikä on helpoin todentaa Unit Test:eillä. Jos testit on kaikkiin featureihin/vastuisiin mitä koodin pitäisi tehdä, mahdollisesti 100% koodikattavuudella (koska jos siellä on koodia mitä ei testata mitenkään niin se koodi ei varmaan tee mitään liiketoimintahyötyä ja voidaan poistaa), niin sitten sisäistä rakennetta voi sitten vapaasti muokata yksinkertaisen ja monimutkaisen välillä helposti. Ilman testejä se on kuumottavaa, koska riski että saa asiakkaan epätyytyväiseksi uusien bugien ja ajan hukkaamisen takia bisneksen kannalta epäolennaisiin asioihin on suuri.
Yksinkertainen design
Simple Design tarkoittaa, että ei koodata mitään extraa/monimutkaista sellaisiin tulevaisuuksiin varautuvaa designia, joka ei välttämättä koskaan toteudu, jos projekti loppuu huomenna ja yksinkertainenkin riittää ja saadaan tehtyä samassa ajassa. Toisin sanoen, jos kovakoodaus riittää, minkä saa valmiiksi puolessa tunnissa, niin ei kannata tehdä 2 viikkoa täydellistä monesta-moneen tietokantamallia (jota ei juuri nyt tarvita)
– vaan sitten kun se seuraava taski tulee missä sitä monimutkaista designia tarvitaan niin refaktoroidaan aluksi se yksinkertainen ratkaisu monimutkaiseksi
<- suurin pelkohan mikä ajaa koodaajat tekemään sen monimutkaisen ratkaisun heti alkuun on pelko muutoksen tekemisestä, eli jos ei harrasteta TDD:tä ja yksikkötestausta, niin sitten muutoksen tekeminen on aina pelottavaa, ja on parempi tehdä monimutkainen ratkaisu nyt jota on (ehkä) helpompi hallita kuin että pitäisi oikeasti refaktoroida koodia – mutta tämähän on pimeän puolen käytäntö joka riistää Asiakkaalta mahdollisuuden tehdä bisneksen kannalta hyödyllisiä asioita samalla ajalla ja rahalla
Teetkö turhaa ja haitallista monimutkaisuutta?
Kunkin refaktoroinnin tarpeellisuutta miettiessä voi lukea myös http://curtclifton.net/papers/MoseleyMarks06a.pdf
eli Out of the Tar Pit eli kun koodaa jotain niin onko se ratkaisu minkä teki ”turhaa ja tarpeetonta monimutkaisuutta” sen kyseisen ongelman ratkaisuun, vai pienin mahdollinen monimutkaisuus. Kaikkien ohjelmistojen kokonaiskokoa rajoittaa sen monimutkaisuus eli jossain kohtaa tulee raja että systeemi on niin monimutkainen että kukaan ei enää tajua sitä
<- tähän itseasiassa ratkaisu on taas yksikkötestaus eli yksikkötesteillä pystyy tekemään monimutkaisemman systeemin kuin mitä kukaan fiksuinkaan koodaaja pystyy ymmärtämään yksin
kun siirtää speksit (koodaajan) muistista (joka on aika rajallinen, asiat unohtuu jo 3kk:ssa) osaksi teknostruktuuria eli koodia.