Avainsana: hinta

Koodaajan erilaiset hatut, refaktorointi

Martin Fowler piti hienon puheen ohjelmoijan erilaisista hatuista. Se upposi ajatusmaailmaani saman tien.

Hänen mukaansa koodia tehtäessä ohjelmoija laittaa päähänsä tietynlaisen hatun käydessään työtehtävään. Tyypilliset hatut ovat

  • koodaus, uusien toimintojen lisäämiseen ja
  • refaktorointi, laadun parantamiseen.

Toki näiden lisäksi löytyy optimoijan hattu, protoilu tai POC-hattu.

iPhone 166Hyvä koodaaja siistii koodinsa aina ominaisuuden luomisen jälkeen, joten miksi refaktoroinnille pitää käyttää omaa hattua? Koska koodi haisee.

Haiseva koodi on (jonkun toisen tekemä) vanha tuotos. Se ei toimi niin tehokkaasti kuin voisi toimia ja se kaipaa pientä tuunausta. Tästä karmeudesta pääsee eroon vain refaktoroimalla. Ohjelmoimista oppiessa huomaa myös oman vanhan koodinsa kaipaavan päivitystä. Koodin hajun lisääntymisen yksi keskeinen syy on sovelluksen kasvaminen ja toimintojen lisääntyminen.

Alkuperäiseen tarkoitukseen käytetty yksinkertainen arkkitehtuuri ei enää toimi, vaan uusien ominaisuuksien lisääminen pakottaa purkkakoodin lisäämiseen, ellei refaktoroi rakennetta uudelleen. Yksinkertaisimmillaan metodikutsu sisältää liian monta parametria ja tarvitaan parametriolio.

Jos koodin hajuun ei kiinnitä huomiota, koodin laatu rapistuu ja koodin rakenne katoaa. Se hukkuu kaikkiin pieniin muutoksiin ja jippoihin. Kompleksisesta koodista seuraa koodaamisen tuska, koska sitä on vaikeampi ymmärtää ja uusien ominaisuuksien liittäminen käy hankalaksi. Aikaa menee hukkaan. Sen sijaan hyvin suunnitellussa ja siistinä pidetyssä koodissa työskentely on vaivatonta ja nopeaa.

Johtoportaalle refaktorointia on turha perustella laadulla, kauniilla koodilla, asinatuntijuudella tai oikealla tavalla tehdä. Perustele rahalla. Sotkuiseen koodiin koodaaminen vie enemmän aikaa kuin pitäisi.

Huomaa, että refaktoroinnin voi joskus jättää tekemättä. Jos haiseva koodi sijaitsee jossain harvoin käytetyssä syrjäisessä osassa, siihen ei tarvitse koskea. Jos haisevaan koodiin törmää päivittäin, se pitää siivota pois. Muutoin joudut tekemään ylimääräistä työtä ja laskutat ylimääräistä asiakkailta. Se on varastamista.

Refaktorointitalkoot ja issuet projektin backlogilla kannattaa unohtaa. Ne putoavat priorisoinnissa aina alaspäin. Sen sijaan korjaa ihan vähän koodia tänään. Paranna laatua taas huomenna, kun törmään heikkolaatuiseen koodiin. Viikkojen ja kuukausien kuluessa koodin laatu paranee. Pian pääset koodaamaan mukavan koodipohjan päälle.

Mainokset

Miksi kirjoittaa yksikkötestejä?

Olen kirjoittanut yksikkötestejä n. 7 vuotta. Vasta viime aikoina olen oppinut uusia tapoja yksikkötestien kirjoittamiseen. Mutta miksi ihmeessä yksikkötestejä kirjoitetaan?

Miksi

  1. Luotettavuus. Yksikkötesti on ainoa tapa varmistaa, että koodi tekee nyt ja tulevaisuudessa haluamani asiat. Jos minä tai joku muu muokkaa koodia, niin yksikkötestillä voi varmistaa, ettei vanha toiminnallisuus mene rikki.
  2. Yksikkötestillä testaaminen käy nopeammin, jos testiä varten pitää sovellus saada tiettyyn tilaan. Testaajan sisäänkirjautuminen ja erilaisten testitapausten luominen vie hyvän tovin.
  3. Parempilaatuinen koodi. Yksikkötestattava koodi on yksinkertaista. Yksikkötestejä kirjoittaessa jättimetodit ja monimutkaiset kokonaisuudet pikkoutuvat pienempiin osiin kuin itsestään. Muut kehittäjät lukevat tällaista koodia meilummin kuin 2000 rivin hirviömetodia, jossa on runsaasti if-lohkoja.
     
    Lisäksi muilta kuultua:

  4. Vähentää koodista löytyviä virheitä (bugit).
  5. Voi tehdä suuria muutoksia koodiin nopeasti.
  6. Välitön palaute koodatessa. Tiedät heti koodisi toimivan, kun syttyy vihreä valo.
  7. Testien avulla näkee miten metodin on tarkoitus toimia.
  8. Testien avulla ymmärtää koodin rakenteen paremmin.
  9. Yksikkötestin avulla pääsee helposti liikkeelle koodaamisessa, jos pitää luoda suurempi kokonaisuus.
  10. Testien kirjoittaminen on hauskaa.

Se maksaa

Pieniä erilaisia asioitaNiin maksaa. Yksikkötestien kirjoittaminen vie hieman enemmän aikaa, mutta menetetty aika ja raha saadaan takaisin virheiden vähentyessä (luotettavuus), tuoteen laadun parantuessa (asiakastyytyväisyys), ylläpiettävyydessä (koodia voi muokata ja refaktoroida tai optimoida nopeammaksi) ja virheiden metsästyksen helpottuessa.

Yksikkötestattu koodi sisältää vielä virheitä. Kehittäjä joskus ymmärtää väärin ja kirjoittaa siksi viallista koodia tai unohtaa jonkin erikoistapauksen. Tällöin kirjataan vika. Kirjoitetaan yksikkötesti, jolla todetaan virheen toistuvan. Korjataan koodi. Vanhoista yksikkötesteistä näkee heti, ettei aiempi toiminnallisuus hajonnut. Käsin testattaessa prosessi olisi hitaampi, koska uudelleentestaus kestää.

Mitä ei kannata testata

Käyttöliittymän ulkoasun tai toimintojen yksikkötestaaminen on harvoin kannattavaa. Elementtien sijainti ja ulkoasu korjataan tyypillisesti kerran.

Jos sovellus käyttää omaa tietokantaa, datan oikeellisuutta ei tarvitse testata. Tallennan kantaan aina hyvälaatuista dataa. Mikäli data tulee ulkoisesta järjestelmästä, jonkun rajapinnan kautta, niin testaaminen voi olla perusteltua.

Tiedon oikeellisuus testataan korkeintaan kerran. Tyypillinen tilanne on testata käyttäjän antama syöte esimerkiksi sotu. Kun sosiaaliturvatunnus todetaan olevan oikeassa muodossa, sitä ei tarvitse myöhemmin tarkistaa. Vapaan tekstikentän sisällön tarkistaminen on järjetöntä. Käyttöliittymäkomponenteille voi antaa kentän maksimipituuden, jolloin vältytään turhilta tekstin pituustarkastuksilta.

Kaikkia tapauksia EI testata. Yksikkötesteihin kirjoitetaan joitain mahdollisia virhetapauksia, joilla voidaan varmiistaa metodin hyvä käytös virheellisellä syötteellä esim. null. Jos koodi laskee jotain, riittää todeta induktiivisesti, että se toimii. Siis tapauksessa 0, perusarvot. Tapauksessa yksi ja n+1. Yksikkötestin sisällä ei pitäisi koskaan olla for-silmukkaa.

Mitä seuraavaksi

Ota kehitysympäristö esille ja aloita yksikkötestien kirjoittaminen!

Katso myös

Ohjelmistojen hankinta

Kirjoitukseni menee ohi ohjelmoinnin, hankinnan puolelle. Minua ottaa päähän, kun kunta tai julkinen instanssi hankkii itselleen ohjelmiston väärin perustein. Ostetaan halvin, eikä se mitä tarvitaan.

Otso Kivekäs listasi hyvin erilaiset ohjelmistojen ostotavat. Näiden lisäksi kannattaa kysyä eri kunnista ja toimijoilta onnistuneista projekteista. Mikä johti onnistuneeseen hankintaan? Miten määritellään hyvä tarjouspyyntö? Menen asian edelle.

Kivekäs esittää kolme hyvää tapaa hankkia tarvittava ohjelmisto:

  1. Ostamalla palveluna (pilvestä)
  2. Ostamalla valmiin standardituotteen
  3. Teettämällä järjestelmän avoimena

Ensimmäinen on halvin ja yleensä vaivattomin ylläpitää. Toinen on kalliimpi, mutta senkin saa heti käyttöönsä. Viimeinen vaihtoehto työllistää kaltaisiani tekijöitä.

Hankkijan kannattaa välttyä toimittajaloukulta. Tarjousta muodostaessa pitää arvioida hinnan lisäksi tekijöiden kokemusta, alakohtaista kokemusta ja toimittajan taustoja. Jotta hinta ei määräisi koko projektin tekijää, se voi muodostaa 40 % hyväksyntään johtavasta pisteytyksestä. Tällöin päättäjät voivat valita haluamiensä kriteerien perusteella parhaat tekijät. Ohjelmistopuolellakaan ei voi ostaa hyvää halvalla.

Kuten Kivekäs mainitsee, pitää tehdystä ohjelmistosta löytyä:

  • Julkiset rajapinnat, joiden avulla tiedon saa muihin järjestelmiin (ilmaiseksi). Jos järjestelmä on kehitetty veronmaksajien rajoilla, kerätyn tiedon voi antaa myös julkisesti käytettäväksi. Vrt. Helsingin bussien seuranta kännykkäsovelluksella.
  • Standardien käyttö. Standardin mukaista koodia voi kuka tahansa lukea ja toimittajan vaihtaminen on mahdollista.
  • Vaiheittainen julkaisu, jonka avulla voidaan alusta asti seurata ohjelmistokehityksen kulkevaan oikeaan suuntaan.
  • Modulaarinen arkkitehtuuri skaalauksen ja ylläpidettävyyden takia.

Nostaisin nämä tärkeimmiksi, vaikka muutkin esitetyt kohdat ovat pakollisia hyvän ohjelmiston toimituksessa.

Ohjelmistojen kehittäjänä ja veronmaksajana haluan tehdä ja ohjata ostajat teettämään hyviä projekteja. Jos projektin ”onnistumisen” ainoa kriteeri on hinta, niin saa sekundaa. Pyydän päättäjiltä viisastumista.