Ajattelu

Ajatuksia ohjelmistokehityksestä, arkkitehtuurista, asiakkaista ja siitä, mitä tuotantojärjestelmät opettavat ajan mittaan.

Thinking

1. Kuunteleminen on tärkeämpää kuin elegantti ratkaisu Link to heading

Olen ollut etenkin urani alkupuolella toteuttamassa IT-ratkaisuja, jotka eivät ole vastanneet asiakkaiden tarpeisiin.

Syy on ollut aina sama: projektissa on kehitetty hieno tekninen ratkaisu ongelmaan, joka on ollut olemassa ainoastaan kehittäjien mielikuvissa.

Vuosien mittaan olen oppinut tulkitsemaan asiakkaiden tarpeita, tekemään niihin omia lisäehdotuksiani, ja toisaalta ennustamaan jonkin verran tulevaisuutta. Näin tekniset ratkaisut onnistuvat ratkaisemaan oikean ongelman ja niiden elinkaaresta tulee oikean mittainen.

2. Integraatiot ovat aina projektien hankalin osa Link to heading

IT-projektit ovat hyvin suoraviivaisia toteuttaa silloin, kun asiakkaan tarpeet ja vaatimukset ovat tiedossa ja toteutuksen voi tehdä itse.

Vaikein osa liittyy käytännössä aina integraatioihin.

  • autentikointi ja käyttöoikeudet
  • maksaminen ja tuotteiden hallinta
  • tuotteiden toimittaminen asiakkaille
  • kytkökset vanhoihin järjestelmiin

Suuri osa ohjelmistokehityksestä on erilaisten epätäydellisten järjestelmien yhteensovittamista. Kehittäjät tekevät oletuksia siitä, miten joku toinen järjestelmä toimii, ja myöhemmin oletukset osoittautuvat vääriksi tai puutteellisiksi.

Integraatioiden suunnittelussa auttaa se, että ei tee vahvoja oletuksia ulkopuolisten järjestelmien toimivuudesta ja luotettavuudesta. On paras lähteä siitä, että ne ovat hitaita ja saattavat lakata toimimasta milloin tahansa. Silloin oma järjestelmä selviytyy odottamattomistakin ongelmatilanteista.

3. Tuotantojärjestelmän uudelleenkirjoitus epäonnistuu usein Link to heading

Vuosien varrelle on mahtunut sekä onnistuneita että epäonnistuneita tuotantojärjestelmien uudelleenkirjoitusprojekteja.

Sellaiset projektit ovat yleensä epäonnistuneet, joissa uusi järjestelmä on yritetty kehittää ensin täydelliseksi kopioksi vanhasta. Siirtymää ei saada välttämättä koskaan vietyä loppuun, koska vanhaakin järjestelmää kehitetään edelleen eikä uudesta tule koskaan täydellistä.

Onnistuneita projekteja yhdistää se, että siirtymä on toteutettu asteittain. Uusi järjestelmä on otettu käyttöön vanhan järjestelmän rinnalle. Toimintoja on siirretty hiljalleen uuteen järjestelmään, kunnes vanha järjestelmä on lopulta jäänyt tarpeettomaksi ja voitu sammuttaa.

4. Hyvä arkkitehtuuri vähentää työn ja ajattelun tarvetta Link to heading

IT-järjestelmien arkkitehtuurin perimmäinen tarkoitus on aina vähentää tulevan työn määrää. Yleensä se tarkoittaa samalla kompleksisuuden hallintaa siten, että järjestelmän osat eivät pääse kehittymään liian monimutkaisiksi.

Hyvin suunniteltu arkkitehtuuri vähentää:

  • päätöksiä
  • koordinaatiota
  • koodaustyötä
  • kompleksisuutta
  • ylläpitokuormaa

Hyvä arkkitehtuuri auttaa:

  • tekemään oikeista valinnoista itsestäänselviä
  • työskentelemään järjestelmän eri osien parissa itsenäisesti
  • vähentämään asioiden toistamista ja hyödyntämään valmiita komponentteja
  • pitämään kompleksisuuden hallinnassa, kun järjestelmän eri osien välillä on selkeät rajat
  • automatisoimaan kehittämistä, tuotantoonvientejä, valvontaa ja päivityksiä

5. Näkyvyys hajautetun järjestelmän tilaan on elintärkeää Link to heading

Asynkroniset prosessit näyttävät usein yksinkertaisilta suunnitelmissa ja kaavioissa.

Tuotannossa ne muuttuvat nopeasti vaikeiksi hallita:

  • mikä vaihe epäonnistui?
  • tarvittiinko uudelleenyrityksiä?
  • tapahtuiko aikakatkaisuja tai viiveitä?
  • jäikö prosessi lopulta kesken?

Erityisesti IoT-laitteiden provisiointi on opettanut, että prosessin tilaan täytyy olla selkeä näkyvyys hallintaliittymästä.

Pelkkä lokien kerääminen auttaa järjestelmien ongelmien selvittelyssä, mutta yleensä tarvitaan parempaa observoitavuutta, jolla saadaan ymmärrys järjestelmän käyttäytymisestä kokonaisuutena.

6. Ominaisuus ei ole valmis ennen kuin se on oikeasti testattu Link to heading

Me ohjelmistokehittäjät ajattelemme usein, että kun olemme saaneet uuden ominaisuuden toteutettua, se on valmis.

Ajattelutapa johtuu siitä, että rakennamme oman päämme sisällä mallin todellisuudesta. Toteuttamamme koodi vastaa tätä mallia mutta ei välttämättä todellisuutta.

Käytännössä uutta ominaisuutta täytyy aina testata ainakin kertaalleen, jotta näkee miten hyvin pään sisäinen mallimme lopulta vastasi todellisuutta ja tuliko toteutuksesta toimiva.

Mitä monimutkaisemmasta kokonaisuudesta on kyse, sitä laajempaa testaamista se vaatii.

7. Täydellinen yhtenäisyys ei ole realistinen tavoite Link to heading

Pitkäikäiset järjestelmät sisältävät lähes aina eri aikakausien ja eri ihmisten tekemiä päätöksiä.

Nimeämiskäytännöt vaihtuvat. Tiimit vaihtuvat. Teknologiat vaihtuvat.

Täydellisen konsistenssin tavoittelu voi aiheuttaa enemmän haittaa kuin hyötyä. Jokainen refaktorointi vie aikaa pois jostain muualta ja aiheuttaa usein itsessään lisää ongelmia.

Sama pätee tekoälyllä generoituun koodiin. Joskus sen tekemä ylimääräinen koodi ja erilaiset nimeämiskäytännöt ovat hyväksyttäviä kompromisseja.

Ongelmia syntyy silloin, kun:

  • kehittäjät eivät enää ymmärrä sovelluksen rakennetta
  • virheiden syyt hämärtyvät
  • kompleksisuus alkaa kumuloitua

Tärkeintä ei ole täydellinen siisteys vaan se, että järjestelmää pystyy edelleen turvallisesti korjaamaan ja jatkokehittämään.

8. Tekoäly ei poista tarvetta hyvälle arviointikyvylle Link to heading

Tekoälypohjaiset työkalut muuttavat ohjelmistokehitystä nopeasti juuri nyt, ja se on hyvä asia.

Tekoäly on monessa suhteessa ylivertainen ihmiseen nähden.

  • Se pystyy huomioimaan isonkin projektin kaiken koodin yhtäaikaisesti
  • Se on väsymätön toteuttamaan rutiiniluontoisia asioita
  • Se löytää toteutuksista monia ajatusvirheitä, jotka ihmiseltä jäävät huomaamatta
  • Se ei välitä, vaikka sille jankuttaa yhä uudelleen samoista asioista

Toisaalta tekoäly ei ole kovinkaan hyvä käyttämään omaa arviointikykyä ratkaisuja tehdessään.

Tekoäly toimii parhaiten ohjelmistokehityksen osana silloin, kun projektiin on jo suunniteltu vakaa perusta:

  • Tietorakenteet ja tietokannat
  • API-rajapintojen perusrakenteet
  • Funktioiden ja muuttujien nimeämiskäytännöt
  • IaC- ja devops-ratkaisujen perusrakenne
  • Ylipäätään riittävästi koodia, josta ottaa mallia

Tällaisen perustan päälle rakentaessa tekoälylle voi antaa aika laajojakin itsenäisiä tehtäviä.

Viime kädessä tekoälyn luomiin ratkaisuihin täytyy kuitenkin suhtautua samoin kuin ihmistenkin tekemään koodiin. Toisen silmäparin on aina syytä tarkistaa se kertaalleen ennen tuotantoon viemistä.