Miksi ohjelmistoprojektit epäonnistuvat

Ohjelmistoprojektit viivästyvät usein tai niiden laatu jättää toivomisen varaa. Tiivistettynä ongelmat johtuvat pääosin siitä, ettei oikeastaan tiedetä mitä tehdään, tallotaan toisten varpaille ja työaikaa tuhlataan tuottamattomaan työhön (ns. bikeshedding)

Vaatimukset ja menetelmät

Ei ole mitenkään harvinaista, ettei ohjelmiston tilaaja tiedä tarkalleen mitä haluaa. Alkuperäisten vaatimusten pohjalta tehtyjen valintojen (ohjelmointikieli, alusta, tietokanta, kirjastot jne.) muuttaminen on sitä työläämpää mitä pidemmälle ohjelmistoa on ehditty tehdä. Ohjelmistoprojekteissa suuretkin muutokset ovat "ihan pikkujuttuja" ainakin tilaajan ja myyjän mielestä. Talonrakennusprojektissa ei varmaan menisi viemärien ja vesipisteiden siirto läpi "pikkujuttuna" siinä vaiheessa, kun wc:n mikrosementtiseinään ollaan kiinnittämässä vessapaperitelinettä.

Vaatimukset myös muuttuvat tai hämärtyvät välikäsien kautta kulkiessaan. Määrittelydokumenttiin jätetään ehkä kirjaamatta itsestäänselvyydet, jotka eivät lopulta olekaan niin itsestäänselviä ja tehdään vääriä oletuksia. Jos kaksi tietokenttää voi saada kolmenlaisia arvoja, peruskäyttäjä näkee siinä 2-3 kombinaatiota, peruskoodari 6 ja hyvä koodari 9. Oikeasti niitä on 16, koska kukaan ei muistanut null checkiä. Määrittelydokumentissa noista on mainittu nuo 2-3.

Usein vain oikeellisten käyttötapausten vaatimukset on esitetty ja virheelliset tapaukset on sivuutettu kokonaan. Vaatimus saattaa olla esim. "... voi syöttää numeron muodossa 123.45". Ennen pitkää joku kirjoittaa kenttään "123,45" ja jotain menee rikki. Siinä missä veitsen leivänpaahtimeen työntänyt voi syyttää vahingosta vain itseään tietojärjestelmissä nämä ovat toimittajan syytä ja pitäisi "korjata" samalla rahalla, vaikka ohjelmisto vastaakin vaatimuksia.

Vesiputousmallilla toteutettuna tilaajan ensikosketus ohjelmistoon on vasta projektin loppupäässä. Siinä vaiheessa on kiva huomata, että kehitys lähti väärille raiteille noin kahden viikon kohdalla.

Ketteriä menetelmiä käytettäessä koodarit ovat laput silmillä eivätkä näe projektista kuin kahden viikon sprintin aikana toteutettavat asiat. Seuraavassa sprintissä 41 viittausta objektin IsPublic-kenttään muutetaan muotoon Status, koska boolean ei enää riitäkään esittämään kaikkia tiloja, vaan se pitää muuttaa enumiksi. Pari kohtaa JavaScriptissa unohtuu, koska siellä Refactor -> Rename ei ole luotettava. Päivityksen jälkeen kaikki artikkelit menevät "julkaistu" -tilaan tallennuksen yhteydessä. Myös ne testaillessa tehdyt nolot jutut.

Parannusehdotuksia

Standardit

Standardeja noudatetaan monesti vain sinnepäin tai niitä ei ole. Esim. luulisi, että niinkin yleinen ja vuosikymmeniä tunnettu toiminnallisuus kuin päivämäärän ja kellonajan valitseminen selaimella olisi hoidettu niin, että käyttäjä voisi valita arvon omien kulttuuriasetustensa mukaisella komponentilla ja koodissa sen saisi luettua vakioformaatissa. Mutta ei ole, vaan tarkoitukseen pitää aina etsiä lisäpalikka, jonka saa säädettyä halutunlaiseksi.

Liian monta kokkia

Toiminnallisuuden toteuttamisen on arvioitu kestävän 10htp (henkilötyöpäivää). Kehittäjä 1 toteuttaa 50% toiminnallisuudesta 5htp aikana. Seuraavassa sprintissä kehittäjä 2 jatkaa. Hän käyttää päivän jo valmiin koodin tutkimiseen sekä lisäksi pari tuntia kehittäjä 1:n kanssa läpikäyntiin. Sitten hän toteuttaa 30% lisää käyttäen siihen 3htp. Nyt 80% toiminnallisuudesta on valmiina, mutta aikaa on kulunut jo 9,5htp (5htp + 1htp + 2*2h + 3htp). Kehittäjä 3 tekee seuraavassa sprintissä toiminnallisuuden loppuun. Koodia on nyt jo vähän enemmän ja hän käyttää perehtymiseen 1,5htp ja pitää parin tunnin palaverin kehittäjien 1 ja 2 kanssa. Itse toteutukseen hän käyttää arvion mukaisen 2htp. Nyt toiminnallisuus on valmis ja aikaa meni yhteensä vähän vajaa 14htp (9,5htp + 1,5htp + 3*2h + 2htp). Kehittäjät 2 ja 3 eivät kuitenkaan täysin sisäistäneet muutostensa vaikutusta olemassa olevaan koodiin ja aiheuttivat muutaman bugin, joiden korjaamiseen meni testailun jälkeen vielä pari päivää. Näin ollen aikaa meni kokonaisuudessaan lähes 60% arvioitua enemmän. Kaikki kehittäjät ovat kuitenkin osaavia ja heistä kuka tahansa olisi tehnyt toteutuksen arvioidussa 10htp:ssä yksin. Olisi sinne pari bugiakin jäänyt, mutta oman tekeleensä tuntien olisi ajatushäröt löytyneet minuuteissa.

Arvioitua suurempi työmäärä ei ole ainoa negatiivinen asia mitä tällaisesta työnjaosta seuraa. Nyt kukaan ei ole täysin perillä miten tämä osa-alue sovelluksesta toimii, eikä näin ollen pysty tarkkaan arvioimaan tulevien toiminnallisuuksien vaativuutta tai vaikutuksia. Jokainen tekijä lisää aiheuttaa koodiin spagettia, koska rikkomisen pelossa yritetään välttää refaktorointia. Koodi ei ole niin yksinkertaista kuin se voisi olla. Ylimääräinen datan pyörittely johtaa lisääntyneeseen suoritin- ja muistikuormaan sekä mahdollisesti kutsuihin ulkoisiin järjestelmiin (esim. tietokanta). Kaikki tämä huonontaa laatua mm. hidastamalla ja aiheuttamalla epävakautta.

Joku ehdottaa koodauskäytänteiden ja yksikkötestien käyttöönottoa. Kaikkien mielestä ajatus on hyvä, muttei kukaan niitä oikeasti halua. Ei vaan haluta aiheuttaa eripuraa (Abilenen paradoksi). Ex java-tyyppiä ärsyttää aaltosulkujen laittaminen uudelle riville ja ex c++ -tyyppi ei voi käsittää miten kenttiin ei laitetakaan m-etuliitettä. Kaikkia ärsyttää eslinterin 251 herjaa puuttuvista tai ylimääräisistä välilyönneistä, jotka eivät vaikuta toimintaan mitenkään. Koneille asennetaan lisäosa, joka korjaa nämä automaattisesti. Nyt jokaisessa commitissa on 72 muuttunutta riviä tämän takia ja ne pari oikeasti muuttunutta riviä hukkuvat niiden sekaan.

Yksikkötestejä kirjoitellaan muodon vuoksi muutamia, jotta testikattavuus pysyy määritellyn rajan paremmalla puolen. Palvelun lisääminen luokan konstruktoriin aiheuttaa 164 yksikkötestin rikkoutumisen ja koodari menettää elämänhalunsa. Urakasta voi selvitä vain katsomalla hauskan kissavideon jokaisen korjauksen jälkeen. Rikkoutuneiden testien nimi ja toiminta eivät vastaa toisiaan, joten ne poistetaan tai niitä muutetaan kunnes ne menevät läpi. Näin testien oikeellisuus muistuttaa vain etäisesti vaatimuksia muutaman iteraation jälkeen.

"Kaikki tekee kaikkea" -ajattelumalli lisää myös työn organisoinnin tarvetta ja haastavuutta sekä tiimin jäsenten välisiä kommunikointikanavia. Tiimiin palkataan uusi tyyppi, jonka pääasiallinen tehtävä näyttäisi olevan Jira-workflown muuttaminen joka sprintissä. Otetaan myös käyttöön uusi chat-sovellus ja tiedostonjakopalvelu, että kaikki tieto saadaan varmasti levälleen ja ruutuun jatkuva tulva notifikaatioita. Päivittäin jokainen kertoo mitä on tehnyt, vaikkei kukaan kuuntele tai ainakaan muista vartin päästä. Toisten puheenvuoron aikana katsellaan puhelimella meemejä instagramista. Standuppien ja palaverien jälkeen kehittäjiltä menee tunti päästä takaisin flow-tilaan.

Parannusehdotuksia

Tuntemattomat tekijät

Ehkä turhin hidaste on järjestelmiin pääsyn odottelu. Tunnusten, palomuuriavausten, vpn:n, turvaselvitysten jne. selvittely käynnistetään vasta, kun niiden tarve on ASAP. Tähän liittyy myös rajoitettu pääsy järjestelmiin. Tarkoitan tilannetta, jossa rajapintaan pääsee esim. vain asiakkaan virtuaalipalvelimen kautta, jossa ei ole (eikä saa asennettua) kehitystyökaluja. Testisovelluksilla lokirivejä printtaamalla on moninverroin hitaampi selvittää mitä jokin "on syönyt" kuin paikallisesti debuggerit, verkkoanalysaattorit yms. päällä ajettuna.

Aiemmissa projekteissa toiminnallisuus A on toteutettu käyttäen kirjastoa X ja B käyttäen kirjastoa Y. Kokonaisuus on arvioitu näiden pohjalta, muttei huomattu että X ja Y toimivat ohjelmistoalustan eri versioilla eikä vaihtoehtoisia kirjastoja ole, jolloin toinen pitää toteuttaa alusta alkaen itse.

Vaatimuksiin liittyen täsmentäviin kysymyksiin vastausten odottelu on täysin tuottamatonta työtä.

Parannusehdotukset

Inhimilliset tekijät

Teknologioita valitaan väärin perustein. Talossa pisimpään ollut valitsee samat teknologiat kuin 10v sitten, koska "näin täällä on ennenkin tehty". Myyntitykki ehdottaa blockchainin ja AI:n käyttöä, koska ne näyttävät hyvältä portfoliossa. Kaikki pitää olla myös serverless, koska asiakas luki siitä teknologia-alan julkaisusta viime viikolla.

Koodaritkin ovat ihmisiä ja tekevät inhimillisiä virheitä. Tietokone vain on armoton virheille ja yksikin väärä merkki (== eikä !=) voi maksaa ihmishenkiä tai ison kasan rahaa.

Parannusehdotuksia