Laadukas ohjelmistokehitys vaatii järjestelmällisyyttä, pikkutarkkuutta ja huolellisuutta. Potentiaalisia bugeja voi olla millä tahansa koodirivillä, ja nykyaikaisissa isommissa ohjelmistoissa on helposti satoja tuhansia tai jopa miljoonia rivejä koodia. Yksikin bugi voi aiheuttaa ohjelman kaatumisen, tietojen katoamisen, tietovuodon tai minkä tahansa muun ei-toivotun toiminnallisuuden. Erittäin epäonnisessa tapauksessa ohjelman väärä toiminta voi johtaa esimerkiksi potilaan kuolemaan (esim. Therac-25) tai lentokoneen putoamiseen (esim. 2015 Seville Airbus A400M Atlas crash). Tässä kirjoituksessa esittelen omat viisi teesiäni huolelliseen koodin tuottamiseen. Ohjelmiston laatu riippuu monista tekijöistä ja laatukriteereitäkin on monia. Näissä teeseissä keskitytään lähinnä koodin tuottamisessa oleellisiin asioihin, käytännössä tietynlaiseen ajattelutapaan, jota laatutietoisen ohjelmistokehittäjän tulisi soveltaa: varmistu, epäile, tarkista.

crown_i Lue ja ymmärrä koodi ennen kuin muokkaat sitä.

Skooppi, joka täytyy ymmärtää, että voi tehdä muutoksia joihinkin koodiriveihin, on suurempi kuin kyseiset koodirivit. Yleensä se on vähintään funktion tai luokan/moduulin kokoinen. Joskus yhden rivin muutos voi vaatia jopa hyvin perusteellista tuntemusta koko softasta, jolloin sen tekemiseen täytyy nähdä työtä ja vaivaa, jotta muutos tulisi tehtyä oikein. Muuttuneet koodirivit per päivä eivät kerro tuottavuudestasi mitään.

crown_ii Älä arvaa tai oleta puutteellisin perustein.

Oletetaan, että sinulla on itse kehittämäsi API, jossa olet toteuttanut assert-palveluja. Olet kirjoittamassa koodia Python2-kielellä ja rajapinnassasi on palvelu, jota voit kutsua seuraavasti: my_assert(expression, description). Sitten kuulet, että Pythonissa on oma assert, ja päätät vaihtaa koodin käyttämään sitä: assert(expression, description). Arvaa, mitä tapahtuu? Tsot tsot! Ei pidä arvata, vaan RTFM! API on sopimus – se pitää lukea ennen kuin sen allekirjoittaa. Muuten annat suostumuksesi laittaa pärstäsi pen*s enlargement -mainoksiin tai mitä sopimuksen laatija ikinä keksikään siihen kirjoittaa tai jättää määrittelemättä.

crown_iii Ole epäileväinen koodin suhteen.

Jos sinulla on pienintäkään epäilystä jostakin koodinpätkästä, niin yritä vakuuttua sen oikeellisuudesta joko itse analysoimalla tai kysymällä sen kehittäjältä, miten ja miksi koodi toimii (jos toimii). Tuottavuussyistä tätä periaatetta ei voi aina noudattaa riippuen koodipohjan laadusta. Hyvässä koodipohjassa on varaa käyttää aikaa epäilyksien tarkistamiseen, koska niitä esiintyy harvemmin. Huonossa koodipohjassa epäilyksiä herää jatkuvasti, ja “pahimmillaan” epäilyksien tutkiminen johtaa usein bugien löytymiseen. Vaikka näiden selvittely parantaisi laatua, selvittelyyn ja korjaamiseen saa kulutettua halutessaan rajattoman määrän aikaa. Hyvä koodipohja mahdollistaa tehokkaan työskentelyn, koska siihen voi epäilyksien herätessä toisaalta luottaakin enemmän. Esimerkiksi jos tiedetään, että API-dokumentaatiot on yleisesti tehty hyvin laadukkaasti, niihin voi tällöin luottaa ja epäilykseen liittyvät tutkimukset voidaan useimmiten päättää rajapintoihin eikä niiden toteutuksia tarvitse tarkistaa.

crown_iv Ole epäileväinen ohjelman toiminnan suhteen.

Jos ohjelma palauttaa arvon 3,141, kun ehkä kuvittelit sen palauttavan 3,142, niin toimiiko ohjelma oikein? Ehkä kyse on liukulukujen pyöristysvirheestä? Ja mitä väliä – tuohan on aivan riittävällä tarkkuudella oikein, kun kyse oli tulostusasetuksesta, joka määrittelee, montako millimetriä sivun marginaaliin jätetään tyhjää tilaa, eikö vain? Väärin. Efektiivinen toiminnallisuus kertoo, toimiiko softa kyseisessä tapauksessa kyseisellä kerralla tuottaen suurin piirtein oikean tuloksen – mutta ei kerro siitä, toimiiko softa oikeasti niin kuin halutaan. Pienetkin poikkeamat odotetusta tai nimellisarvosta voivat käytännön näennäisestä merkityksettömyydestä huolimatta olla hyviä indikaattoreita siitä, että softa toimiikin itse asiassa väärin tai eri tavalla kuin on kuviteltu. Kyse voi olla vain pyöristysvirheestä (liukulukujen toiminta), väärin toteutetusta pyöristyksestä (esim. rounding vs. truncation) tai jostain ihan muusta, jonka tulos sattui olemaan lähellä oikeaa.

crown_v Älä copy-pastea koodia.

Jos olet copy-pasteamassa koodia, ensimmäinen asia on tietysti miettiä, mitä hittoa olet oikein tekemässä. Äärimmilleen vietynä voisi sanoa, että softakehityksessä tarvitaan vain hyvin vähän periaatteita, joita noudattamalla, järjellisesti ja huolellisella työllä, pääsee melko hyvään lopputulokseen. Itse väitän, että DRY KISS riittää pitkälle. Eli Don’t Repeat Yourself ja Keep It Simple, Stupid! Muut periaatteet ovat enemmän tai vähemmän seurausta näistä. DRY-periaatteesta seuraa, että copy-paste-koodille pitäisi olla harvemmin tarvetta. Jos kuitenkin päädyt siihen, että tarvitset saman koodinpätkän kuin jossain muualla, niin kannattavampaa olisi yleensä kirjoittaa se uudestaan kuin copy-pasteta. Syy on se, että usein copy-pastettuun koodiin jää bugeja, koska osa muuttuvista tekijöistä unohtuu ajan ja vaivan säästämisen riemussa muuttaa. Valitettavasti ihminen ei aina jaksa keskittyä kunnolla tylsiin, rutiininomaisiin ja näennäisesti helppoihin tehtäviin. Täten myös koodinpätkän toistamisessa kirjoittamalla piilee se vaara, että koodi tulee brains off -tyylisesti vain kirjoitettua uudelleen eikä aktiivinen ajattelu ulotu kaikkiin yksityiskohtiin. Siksi olisi hyvä tiedostaa asia ja kiinnittää erityistä huomiota lopputuloksen tarkistamiseen, kun on toistamassa koodinpätkää – copy-pastella tai käsin.