Rakkaudesta koodiin

Miten ohjelmoijan tulisi suhtautua omaan koodiin ja ohjelmointiin? Miten ohjelmointiin ja ohjelmoijiin tulisi suhtautua? Onko asiakkaan tarpeet tärkeämpää kuin laadukas ja hyvä koodi? mitä on hyvä koodi? Kuinka monta ihmistä tarvitaan koodaamaan yhtä ohjelmaa?

Vesiputous

Itselleni on hyvin jäänyt mieleeni yksi kuvaaja, jonka suomalainen Visual Basic -kirja avasi erinomaisesti muiden asioiden ohella. En itse ole sitä löytänyt uudestaan, mutta erittäin hyvin mieleeni jäi kyseinen projektin eri vaiheisiin käytettävä aika piirakkadiagrammina. Kyseisessä kuvaajassa ohjelmoinnin osuus oli hyvin pieni eli vain n. 15 %:n siivu, jollaiseksi aikajakauma on käytännössä osoittautunut isoissa projekteissa. Seuraava humoristinen Suomen jääkiekon 1995 vuoden MM-voiton Ihanaa leijonat ihanaa karikatyyri muistuttaa nykyään perinteisestä ohjelmistoalan projektimallista eli vesiputousmallista.

Minkälainen nykyaikana olisi piirakkadiagrammi, jos ohjelmistokehittäjän työaika kuvattaisiin sillä? onko huuhata väittää, että ohjelmistokehittäjän työstä ohjelmoinnin osuus on vain pieni osa työtä. Mielestäni tämä vanha perinteisen projektimallin viisaus on unohtunut vanhojen oppien demonisoinnin myötä.

”Kuinka monta blondia vaaditaan vaihtamaan lamppu?
– Kaksi. Toinen pitää lampusta kiinni ja toinen pyörittää tuolia.”

Kukaan ei tietääkseni ole koskaan väittänyt, että ketterässä ohjelmistokehityksessä ei tarvitsisi suunnitella, määritellä ja testata ohjelmaa [3]. Kyse on vain siitä, että ketterässä ohjelmistokehityksessä sitä tulisi tehdä jatkuvasti, eikä vain painottaen projektin alkupäätä. Samoin kukaan ei tietääkseni ole väittänyt, että perinteisessä projektimallissa ei saa palata vaiheissa taaksepäin.

Hyvin suunniteltu on puoliksi tehty

Iso osa ohjelmoinnista on vain perinteistä iffittelyä eli suomeksi jossittelua, joihin moni ohjelmoija kompastuu nokkeluuttaan, kun tekevät liian moni-mutkaisia kikkareita. Ehtolauseiden ongelma on siinä, että se edellyttää valtavaa haara- taikka polkukattavaa testausta joko manuaalisesti debuggerin kanssa tai sitten automatisoiduilla yksikkötesteillä.

Näitä asioita voidaan mallintaa perinteisellä vuokaaviolla, joka on ajalta ennen ohjelmistoalaa. Jos jotain ei vuokaaviolta löydy testauksessa, niin ohjelmaa ei oteta tuotantoon. Näin hieman pelkistäen, ohjelmien testaus on oma laaja kokonaisuutensa.

Kuva 2. Vuokaavio eli Flow Chart UML-tyyliin. [1]
Miksi näin ei sitten aina tehdä koko ohjelmalle? Kyse on hyvin suurelta osin siitä, että kattavan vuokaavion piirtäminen ja automaatiotestien tekeminen vievät valtavasti aikaa. Kyse ei ole siitä, ettäkö ei olisi olemassa menetelmiä niiden tekemiseen. Vielä kun tähän lisätään kattava määrittelytiedosto, niin ajankäytöllisesti ei enää ehditä kehittämään ohjelmaa.

Yksi iso ongelma perinteisessä projektimallissa on jatkuvasti päivitettävät suunnitelmat. Puhumattakaan odotettavista muutoksista asiakkaan tarpeeseen, jota asiakas itsekään ei yleensä tiedä, vaan olettaa ohjelmistokehittäjien tietävän.

Projektimallin speksaus rajoittaa ohjelmointia, ketterässä kehityksessä on perimmiitään ihan eri filosofia. Projektimalli sopii hyvin mm. rakennusprojekteihin, joissa halutaan minimoida rakennusaika eri toimijoiden kesken. Ohjelmointi ei ole mitään pikakirjoittamiskilpailua, vaan muistuttaa enemmänkin blogikirjoittamista.

Kuva 1. Loppu tällaiselle ohjelmistokehitykselle. [5]
Asia ymmärrettiin kunnolla vasta vuosituhannen vaihteen IT-kuplan aikaan, kun sijoittajien rahat olivat loppu ja ei tullut mitään tulosta. Oli pakko keksiä jokin muu parempi tapa tehdä ohjelmia, kehittää kokonaan uusi ajatusmalli tyhjästä. Yhteiskuntia, ohjelmia ja muita vastaavia monimutkaisia järjestelmiä ei vain osata kehittää ylhäältä alaspäin johdetulla viisivuotissuunnitelmalla. Moni on varmasti sitä mieltä, että teoriassa asiat voivat toimia optimaalisesti, mutta käytännössä asiat ovat niin kaaottisia, ettei kukaan osaa niitä kaikkia käsitellä helposti.

Työajanseuranta

Työajanseuranta on alasta riippumatta hyvin ärsyttävää. Jokaisella alalla varmasti hyvin ymmärretään, että ihminen ei paljoa ehdi tai pysy tekemään työpäivän aikana. Tätä varten ennen teollistumista haalittiin viholliskansoista orjia, jotka tekivät raskaita töitä. Nykyään jopa kaupan kassat korvataan automatisoiduilla järjestelmillä. Myös tietojärjestelmissä ihminen on suurin pullonkaula, eikä ohjelmointi ole tähän mitenkään poikkeus.

Ohjelmoijan odotettava työajankesto on kaikista vaihtoehdoista mahdollisimman pessimistinen arvio. Sen jälkeen kyseisen arvion saa kertoa piillä. Tämä on odotettavissa oleva työaika. Tämän voisi myös sanoa niin, että työajasta vain 15 % kuluu ohjelmointiin. Ajankäytön ymmärtäminen on monelle todella vaikeaa kunnolla ymmärtää, että miten paljon kaikenlaista on ja miten vähän saa aikaan.

Asiaa voidaan lähteä myös LoC-käsitteestä eli koodiriveistä. Jos ohjelmoija kehittää ohjelmaa tasaisen hyvällä 100 rivin päivävauhdilla ja vuodessa on 200 työpäivää. Kun ohjelman koko on 100K riviä koodia, niin työaikaa ohjelman kehittämiseen kuluu 5 vuotta. Vastaava ohjelma 40K koodirivisenä 50 rivin päivävauhdilla valmistuisi vuoden etuajassa. Näin yhtenä perinteisenä tapana arvioida työaikaa. Vertailuksi Lidlin SAP-pohjainen ERP maksoi 500 M€, työstettiin 7 vuotta ja tulos oli 0 riviä koodia valmiina [4]. Tämä jos mikä vakuuttaa itseni suunnitelmatalouden toimattomuudesta nykymenetelmin.

”I remember feeling so good about myself for the long hours I was working. I remember feeling dedicated. I remember thinking that working at 3 am is what serious professionals do. How wrong I was!” [7]

Koodirivien laskenta on monien mielestä erittäin huono tapa tehdä työajan seurantaan, mutta oikein käytettynä kuitenkin paras tunnettu menetelmä. Esimerkiksi ammattikorkeakoulun opinnäytetyöni oli alle 10K riviä C#-koodia, jota myöhemmin laajensin mm. maanjäristyslaskemilla. Koodirivien arviointi vaatii vahvaa ymmärrystä ohjelmoinnista, joten ehkä sen takia turvaudutaan mm. tuntikirjanpitoon.

Tunteja seurataan myös laskutuksen takia, usein ohjelmia myydään joko kiinteähintaisina projekteina taikka sitten tunteina. Kyse on tästä markkinataloudesta, jonka opit eivät erityisen hyvin sovellu immateriaalisten ohjelmien myymiseen. Tämä herkästi johtaa samanlaisiin ongelmiin kuin suunnitelmatalouden tuotesuunnitelussa.

Hyvä koodi

Itse aikoinaan kun ohjelmointia aloitin, niin olin hyvin huolissani omasta osaamisestani. Jotenkin kuvittelin, että ohjelmoinnissa olisi jokin ns. viisasten kivi, jolla kaikki asiat ratkeaa. Kuitenkin asioita ja tapoja on oppinut enemmän ja enemmän, eikä vielä sitä kaiken kullaksi muuttavaa juttua ole tullut vastaan. Ei niin kaavioista, speksauksesta, työkaluista, olio-ohjelmoinnista, opeista, sertifikaateista kuin muistakaan alaan liittyvistä asioita saanut kaiken tekevää. Olen kuitenkin saanut huomata, että olen oppinut aiempaan nähden. Yleensä vaihtoehtojen hyvät ja huonot puolet oppii tiedostamaan, jolloin osaa valikoida tilanteeseen paremman vaihtoehdon.

”We are uncovering better ways of developing
software by doing it and helping others do it.” [3]

Olen ymmärtänyt, että ykkösien ja nollien oikein järjestelyä voi tehdä monella tavalla. Mikään niistä tavoista ei välttämättä ole täysin oikea tai väärä. Jos on rajapinta ulkopuoliselle taholle, portti tai toisen ohjelmoijan tekemä kirjasto, niin se pakottaa tekemään asiat samoin. Tällöin on hyvä, jos asiasta on dokumentaatiota, koska itse ei voi asiaa ratkaista haluamallaan tavalla.

Hyvä koodi on kuitenkin arvokasta, jota en itsekään aina ole ymmärtänyt [9]. En ole aina tiennyt mitä on ERP eli tuotannonohjausjärjestelmä, mutta olen niitä ohjelmoinut. Usein tulee vähäteltyä oman koodinsa arvoa, ei ymmärrä sen olevan valtavien rahasummien arvoista. Yksi Like-nappi voi olla Facebookille miljardien dollarien arvoinen, se tuo käyttäjille valtavasti hyötyä. Samoin Googlen hakukoneen etusivulle ei ole paljon muuta sisältöä kuin vain yksi tekstikenttä, mutta todennäköisesti silti se on paljon parempi kuin mikään muu monimutkaisempi ratkaisu. Koodin arvo on laskennallisesti tulo käyttöasteesta ja loppukäyttäjän siitä saamasta lisähyödystä. Käyttämätön ja asiakasta hyödyttämätön koodi on arvotonta.

Aivan samoin kuin koodirivien määrän laskeminen on ongelmallista työajan seurantana, niin ihan samoin koodin arvon laskeminen työtunteina on typerää. Usein yksinkertaisempi voi olla jopa arvokkaampi, siinä on vähemmän hukkaa ja turhaa roskaa. Etenkin käytettävyyden kannalta yksinkertainen ja selkeä on usein parempi, myös ohjelmakoodin ylläpidettävyyden kannalta yksinkertainen ja selkeä on yleensä parempi. Perinteisen mallin mukaisesti loppuvaiheessa huomatun asian korjaaminen voi olla työmääränä 50 – 200 kertaa isompi kuin projektin alkuvaiheessa [2]. Siis alkuperäisen yhden työpäivän työstä tulee loppuvaiheessa jopa yhden työvuoden lisätyö.

Principles behind the Agile Manifesto

 

We follow these principles:Our highest priority is to satisfy the customer
through early and continuous delivery
of valuable software.
Welcome changing requirements, even late in
development. Agile processes harness change for
the customer’s competitive advantage.

Deliver working software frequently, from a
couple of weeks to a couple of months, with a
preference to the shorter timescale.

Business people and developers must work
together daily throughout the project.

Build projects around motivated individuals.
Give them the environment and support they need,
and trust them to get the job done.

The most efficient and effective method of
conveying information to and within a development
team is face-to-face conversation.

Working software is the primary measure of progress.

Agile processes promote sustainable development.
The sponsors, developers, and users should be able
to maintain a constant pace indefinitely.

Continuous attention to technical excellence
and good design enhances agility.

Simplicity–the art of maximizing the amount
of work not done–is essential.

The best architectures, requirements, and designs
emerge from self-organizing teams.

At regular intervals, the team reflects on how
to become more effective, then tunes and adjusts
its behavior accordingly. [5]

Seuraavat kaksi 1930-luvun opetusvideota antavat mielestäni hyvän kuvan, että minkälaista ketterän kehityksen tulisi olla. On myös tullut selväksi, että ohjelmistoprojektien hallinnan  tulee sopeutua tosimaailmaan, kun sitä ei voi muuttaa. Sen lisäksi että videot muistuttavat tyypillistä onnistunutta ohjelmistokehitystä, ketteryyden nimenomaan kuuluu olla tällaista. Olisi hyvä, jos nykyaikana tehtäisiin vastaava ketterän ohjelmistokehityksen opettamiseksi. Jousituksen kehittäminen tyhjästä on niin monimutkainen asia, että se on hyvin verrannollinen tyypilliseen ohjelmistokehityksen haastavuuteen. Tyypillisesti ohjelmoitavat ohjelmat ovat aivan eri alaa kuin oma koulutus, joten myös sikäli kuvastaa täydellisesti ohjelmistokehitystä.

Jos seuraavia videoita katsoo, niin varmaan herää paljon erilaisia ajatuksia. Itse pidän seuraavan videon yksinkertaisesta ja hauskasta tavasta kertoa rungon suunnittelusta. Toisessa videossa ilmeisesti jotenkin korisuunnitteluun osallistunut sotilaskapteeni laittaa itsensä testiin. Aiheeseeh liittyen mm. CAD eli tietokoneavusteinen suunnittelu on tehnyt jotain hyvääkin korisuunntteluun liittyen. Pakko myös sanoa, että kolmannen videon 1950-luvun auto on paljon tyylikkäämpi kuin uudempi. Nykyään kori ja runko ovat sama asia, kun suunnittelutavat ovat kehittyneet.

Tulevaisuus kautta historian

Tässä blogiartikkelissani käsittelin hyvin monipuolisesti projektin ohjelmistokehityksen hallintaa. Minä kirjoitan blogiani ketterästi, olen niin jo tehnyt kaksi vuotta. Alkujaan työttömänä tätä blogiani aloittaessani mietin, että mihin tämä kaikki johtaa. En vain kyennyt hahmottamaan sitä, joten päätin suosiolla mennä ketterällä menetelmällä, aloittaen kertomaan Rooman valtakunnan Leipää ja Sirkuhupeja -filosofiasta [10]. Mielestäni se oli hyvä alku blogilleni, sisältäen todella paljon sitä, jota itse ajattelin blogini sisältävän.

Miten siis mielestäni ohjelmistokehitystä tulisi opettaa? Koska mussutan ja kritisoin, niin minä koen velvollisuudeksi selittää paremman mallin myös siihen. Perinteinen projektimalli on todella hyvä tapa opettaa teoriassa, joskin se on käytännössä virheellinen. Tämä on todella pelottavaa, kun ajattelee, että on aikoinaan opetettu väärää tapaa vain sen takia, että ei osattu tai haluttu kertoa muuta.

Kuva 3. Aluksi ohjelmointi voi vaikuttaa hyvinkin selkeältä, mutta jossain vaiheessa se muuttuu säätämiseksi.

Mielestäni oikea tapa olisi se, että ohjelmistoalan opiskelijat laitettaisiin tekemään projektia mm. eri alan opiskelijoiden kanssa, kuten vaikkapa helpompina vaihtoehtoina rakennus- tai konealan insinööriopiskelijoiden kanssa. Nämä projektit voisivat kestää vuosia, jolloin tulisi todellista kuvaa ohjelmistoalan projekteista/prosesseista. Voisivat tutkijoiden kammioissa loikoilevat professoritkin hahmottaa, että mitä todellinen miljoonan koodirivin ohjelmistoprojekti on kampusalueen ulkopuolella. Näin opetuksen taso nousisi ketterän kehityksen myötä oppilaitoksissa.

On myös hyvä ymmärtää, että ohjelmakoodi ei yksinkertaisesti ole suoraan kierrätettävää eri projektien välillä, ellei sitä ole tehty sellaiseksi. Tälläinen koodi on geneeristä koodia, joka voi olla kirjasto. Tällöin se soveltuu tiettyyn moneen yleiseen tarkoitukseen hyvin, mutta ei tiettyyn haluttuun tarkoitukseen. Olen kuvaillut sitä seuraavalla itse keksimälläni Kuvalla 4. Yksinkertaisuus on tapa tehdä asia nopeasti. Geneerisyys on tapa tehdä asia moneen tilanteeseen sopivaksi. Toiminallisuus on tapa tehdä ohjelma kattavasti. Näitä kaikkia ei voi helposti saavuttaa, joskaan en väitä sen olevan mahdotonta esim. neuroverkoilla. Unix, Paint ja Passeli ovat kaikki lähellä keskusta ja täydellisesti onnistuneita, mutta silti täysin erillään toisistaan omissa optimaalisissa kategorioissaan.

Kuva 4, Venn Diagrammi ohjelman tarpeista.

Mitä sitten on tulevaisuus, niin en osaa vastata. Itse olen hyvin tuore tapaus ohjelmistoalalla, joka itsessään on hyvin tuore ala. Mahdollisesti itselläni on paljon annettavaa, jotain aiemmin huomaamatonta. Ehkä minusta voi vielä tulla tekniikan tohtori, ehkä ei. Itse luotan jatkuvaan kehitykseen, samaan vahvuuteen kuin 390 jkr. Vegetius totesi Rooman valtakunnan vahvuudeksi.

”We find that the Romans owed the conquest of the world to no other cause than continual military training, exact observance of discipline in their camps and unwearied cultivation of the other arts of war.” – Vegetius, Länsi-Rooma, 390 jkr. [11]

Mielestäni aikalaisen dokumentaation sana painaa niin paljon, että jopa jälkeläisten analyysit historiasta jäävät jälkeen. Itse vertaisin ohjelmistokehittäjän työtä Rooman valtakunnan legionalaiseen, molemmat arvostettuja henkilöitä, kykeneviä toimimaan tilanteen mukaan parhaimmalla mahdollisella tavalla. Parhaansa tekee, niin se riittää: luotto siihen on täydellistä. Sodat ovat hyvin ja kattavasti dokumentoituja, kuten seuraavasta videosta voi huomata.

Rooma oli vahva suurvalta, joka perustui moniin vahvuuksiin. Kristityt kritisoivat kyseistä järjestelmää, mutta silti eivät koskaan kyenneet selittämään sen hajoamista, saati sitten Rooman valtakunnan vahvuuksia. Valtakunta perustui yleisesti hyviksi todetuille yksinkertaisille periaatteille, ei projektimalliin. Ketterä ohjelmisokehitys on kuin Vegetiuksen oppien lukemista; virheistä ja onnistumisista oppimista ilman parempaa tietoa. Ketteryys on siis mielestäni hieman sama kuin yritys ja erehdys -menetelmä. [11]

”We cannot now expect to find a man to teach what he never learned himself. The only method, therefore, that remains of recovering the ancient customs is by books, and by consulting the old historians. But they are of little service to us in this respect, as they only relate the exploits and events of wars, and take no notice of the objects of our present enquiries, which they considered as universally known.” – Vegetius, Länsi-Rooma, 390 jkr. [11]

REFERENSSIT

[1] IT Mayer: UML Activity Diagram

[2] Wiki: Vesiputousmalli

[3] Agile Manifesto

[4] Kauppalehti: Lidl panee jäihin 7 vuotta valmistellun hankkeen – maksanut jo 500 miljoonaa

[5] Robert C. Martin & Micah Martin: Agile Principles Patterns and Practices in C# (PDF)

[6] Robert C. Martin: Clean Code (PDF)

[7] Robert C. Martin: Clean Coder (PDF)

[8] Robert C. Martin: Clean Architecture (PDF)

[9] Portfolioni: autopelin C/C++-lähdekoodit

[10] Tuppu.fi: Panem et circenses

[11] Vegetius: De Re Militari