Käytännön vinkkejä ohjelmistotuotantoon1. Johdanto
Kuva 1: Uusi auto ei sisältä vastaa odotuksia. Harvinaista autoteollisuudessa, mutta ohjelmistotuotannon arkipäivää. Jos mietit aloittavasi tekemään tai teet ohjelmistoja, tässä muutamia käytännön vinkkejä, joista toivottavasti on hyötyä. Kappaleissa 2 - 7 käsitellään itse ohjelmistojen tekemisen prosessia. Kappaleessa 1 on muutamia yleisiä asioita, jotka koskevat kaikkia ohjelmistotuotannon vaiheita. Joissain kohdin tässä tekstissä on otettu esimerkiksi Java-maailmasta löytyviä asioita. Teksti ei ota kantaa onko itse prosessi vesiputousmalli, spiraalimalli, protomalli tai joku muu. 1.1. Termit1.1.1. OhjelmistotuotantoOhjelmistojen tekemiseen ei ole yhtä vakiintunut suomenkielistä termiä, vaan käytössä on samaa asiaa tarkoittavat termit ohjelmistotuotanto ja ohjelmistotekniikka. Tässä tekstissä käytetään termiä ohjelmistotuotanto. 1.1.2. ProsessiProsessi tarkoittaa hallittua toistettavaa työvaiheiden sarjaa, jonka lopputulos on ennakoitavissa. Ohjelmistoja voidaan tehdä ilman prosessia, mutta tästä aiheutuu mm. laatuongelmia, koska lopputulos riippuu täysin tekijöistä. 1.1.3. Malli"1. Johdanto" -kappeleessa mainitut mallit prosessista kertovat miten työvaiheesta toiseen edetään:
1.1.4. Ohjelmistotuotannon työvaiheetOhjelmistotuotanto koostuu seuraavista työvaiheista: määrittely, suunnittelu, toteutus, testaus, käyttöönotto ja ylläpito. Näiden työvaiheiden sisältöön otetaan kantaa kappaleissa 2 - 7. 1.2. DokumentointiDokumentointiin kannattaa käyttää pistää paukkuja. Matalan tason tekninen dokumentointi sujuu luontevasti englanniksi, mutta muun dokumentaation kielen valintaan kannattaa käyttää hetki aikaa. Kielen valintaan vaikuttaa se kenelle dokumentti on tarkoitettu nyt ja kuka sitä mahdollisesti tulevaisuudessa lukee. Kielen valinnan epäonnistuminen vaikeuttaa dokumentointia sekä heikentää dokumentoinnista saatavaa hyötyä. Dokumenttien kuvitukseen kannattaa käyttää aikaa, koska kuvat kertovat tunnetusti "enemmän kuin tuhat sanaa". Lisäksi usein lukijoiden on vaikea keskittyä pitkään vaativaan tekniseen tekstiin, joten kuvat tarjoavat katkoja lukemiseen. Dokumentoi harkiten asioita kahteen kertaan, käytä mielummin viittauksia, jotta ylläpidosta selvitään kunnialla. Tietyissä tilanteissa esimerkiksi ohjelmiston yleiskuvaus on perusteltua kopioida sellaisenaan dokumentista toiseen. Toinen hyvä syy tupladokumentointiin on se, että kaikkia dokumentteja ei toimiteta kaikille tahoille. Hyvin tehty dokumentaatio on hyödyllinen dokumentin kirjoittajalle itselleen, koska siitä käy ilmi tarvittavat asiat - tekijän ei tarvitse muistaa kaikkia asiota. Kirjoittajan hyötynä voidaan pitää sitä, ettei toisten henkilöiden tarvitse henkilökohtaisesti kysellä kirjoittajalta tietoja, jos he löytävät etsimänsä tiedon dokumentista. Ennen varsinaisen dokumentoinnin aloittamista kannattaa miettiä minkälaisia dokumentteja kirjoitetaan ja mitä asioita niihin tulee otsikkotasolla. Näin helpotetaan tekemään dokumentaatiosta looginen, johdonmukainen, luettava ja ylläpidettävä. 1.3. Hukkaan heitetty työMitä pidemmellä ohjelmiston tekemisessä edetään, ettei kaikki osapuolet tiedä tarkkaan mitä ollaan tekemässä, sitä enemmän hukataan työtä, jos jälkikäteen selviää että toinen puhui aidasta ja toinen aidan seipäästä. Sama pätee vikojen havaitsemiseen, koska mitä aikaisemmassa prosessin vaiheessa viat havaitaan ja korjataan, sitä pienemmällä työmäärällä selvitään. Jottei tehdä turhaa työtä, kannattaa prosessin alkupäähän kiinnittää erityistä huomiota. Aina välillä kannattaa pysähtyä kriittisesti arvioimaan jo tehtyä työtä - puuttuuko jotain olennaista, onko jotain turhaa ja onko tuotettu tieto muutoksineen toimitettu kaikkien tietoa tarvitsevien ulottoville. Pitäen samalla mielessä, että prosessin heikoin lenkki kertoo koko prosessin tason. Valitettavan usein aikataulu sanelee käytännön ehtoja. Yllyttämättä venyttämään ohjelmistoprojekteja on silti hyvä pitää mielessä seuraavaa asia. Jos ohjelmistoprojekti myöhästyy vähän, sitä ei kukaan muista vuoden päästä, mutta jos ohjelmisto on susi, sitä joudutaan parantelemaan hamaan tulevaisuuteen. 1.4. Kirjasto esimerkkiLäpi tämän tekstin rakennetaan rinnalla yksinkertaistettu kirjasto järjestelmä, jotta ohjelmistotuotannon eri vaiheet tulisivat käytännönläheisesti käytyä läpi. 2. MäärittelyAluksi määrittelyssä kannattaa muodostaa itselle kuva mitä ollaan tekemässä tutustamalla aiheeseen. Tämä voi tapahtua lukemalla kirjallisuutta tai keskustelemalla henkilöiden kanssa, joilla on selkeä käsitys siitä mitä halutaan, mutta eivät välttämättä ymmärrä tekniikan päälle. Kerää muistiinpanoja, jotka helpottavat varsinaisen määrittelydokumentaation kirjoittamista. Jos määrittelydokumentaation kirjoittamiseen osallistuu useita henkilöitä, sopikaa selvät roolit ja käykää määrittelyn etenemistä säännöllisesti läpi. Muussa tapauksessa asioita tehdään useaan kertaan ja lopputuloksesta tulee sekava jopa ristiriitainen. Määrittelydokumentaatiossa tärkeitä asioita on mm. termien määrittely, vaatimuksien numerointi, vaatimuksien pitäminen lyhyinä ja selkeinä sekä vaatimuksien kategorisointi, jos vaatimuksia on paljon. Vaatimukset voidaan tarvittaessa priorisoida, jolloin on sovittava miten prioriteetit vaikuttavat käytännössä. Jos vaatimuksia joudutaan myöhemmin muuttamaan, vaatimusdokumenttien versiointi on tärkeää. Näin voidaan prosessin myöhemmissä vaiheissa viitata vaatimuksiin, joiden pohjalta työtä on tehty. Määrittely dokumentaatiossa ei oteta kantaan tekniikkaan esim. millä ohjelmointikielellä toteutus tullaan tekemään, tullaanko toteutus ajamaan palvelimella vai asiakkaalla, käytetäänkö tietovarastona tietokantaa jne. Määrittelydokumentaation valmistumisen yhteydessä on hyvä pyytää kirjallinen hyväksyntä ohjelmiston tilaajalta. Näin vältetään tai ainakin minimoidaan mahdolliset epäselvyydet myöhemmin, joiden korjaaminen vie usein paljon aikaa. Määrittelydokumentaatioon pohjautuu kaikki määrittelyn jälkeiset työvaiheet. Testauksen suunnittelu on hyvä aloittaa samaan aikaan määrittelyn kanssa, jotta testaaminen keretään suunnitella riittävän kattavaksi. Kirjasto esimerkin vaatimusten 0.1-versio: Termit: -Kirjasto on paikka, jossa teoksia säilytetään ja josta asiakas niitä lainaa. -Asiakas on yksityishenkilö, joka voi lainata/palauttaa teoksen/teoksia kirjastosta. -Teos on pienin mahdollinen lainauksen kohde esimerkiksi +lehti +kirja +CD-musiikkilevy +C-kasetti +DVD-video +VHS-video +musiikki satu (sis. CD-levyn ja kirjan) Toiminnalliset vaatimukset: 1) Asiakas yksilöitävä 2) Asiakas voi lainata kirjastosta teoksen/teoksia 3) Asiakas palauttaa teoksen/teokset ennen laina-ajan umpetumista 4) Asiakas voi palauttaa teoksen tai teoksia riippumatta lainasiko hän ne kerralla 5) Asiakkaita voi lisätä tai poistaa 6) Asiakkaan poisto edellyttää teosten palauttamista 7) Asiakkaan tietoja voi muokata 8) Asiakkaan tietoja vähintään nimi, yhteystieto 9) Asiakkaan nykyiset lainat nähtävä 10) Asiakkaan nykyiset lainat voi nähdä asiakas tai kirjaston edustaja 11) Teoksen maksimi laina-aika määräytyy tyypin mukaan (kaikkia teoksia ei lainata) 12) Teoksien tyyppejä voi lisätä tai poistaa 13) Teoksen tyypin poisto edellyttää ettei kyseistä tyyppiä käytetä 14) Teoksien laina-aikoja voi muuttaa 15) Teokseien laina-aikojen muuttaminen ei vaikuta lainattujen laina-aikoihin 16) Teoksia voi lisätä tai poistaa 17) Teoksen tietoja voi muokata 18) Teoksen tietoja vähintään nimi, teoksen tekijä, tyyppi, lukumäärä Ei toiminnalliset vaatimukset: 19) Asiakkaan mahdolista käyttää kodistaan 20) Jokaisella sivulla apua-osio 21) Ulkoasua voi muokata kirjastokohtaisesti (Vähintään kirjaston logo, fonttien koot ja värit) 22) Yhtäaikaisia asiakkaita jopa 50, joille vaste 3 sekunnin välein 23) Maksimi viive 0,5 sekunttia 24) Käytettävissä ruuhka-aikana (joka päivä kello 9-18) yli 99,5% 25) Käytettävissä yli 95% ruuhka-ajan ulkopuolella Jos tiedetään muita vaatimuksia, jotka todennäköisesti myöhemmin halutaan toteuttaa, on ne syytä kirjata pienemmällä prioriteetilla jo vaatimusten ensimmäiseen versioon. Esimerkki määrittelystä puuttuu yksinkertaistamisen vuoksi mm. asiakaskohtainen käyttöliittymän kieli, alaikäisten henkilöiden lainojen vastuuhenkilö, montako teosta yksi asiakas voi lainata, mitä käy jos asiakas ei palauta teosta ajallaan, mahdollisuus tallentaa ylimääräistä tietoa esim. syy miksi käyttäjä/teos on poistettu, aika jolloin käyttäjä/teos on lisätty/poistettu, teoksien varaaminen, muistutukset määräajan lähestymisestä, kirjaston yhteystiedot ja aukioloajat tai ilmoitus varatun teoksen vapautumisesta yms. 3. SuunnitteluSuunnittelu perustuu vaatimusten tiettyyn versioon, joka on syytä dokumentoida. Suunnittelu koostuu kolmesta osasta, joita voidaan tehdä rinnakkain ja missä tahansa järjestyksessä. 3.1. Käyttöliittymän suunnitteluKäyttöliittymäsuunnittelu sisältää luonnokset käyttöliittymän tärkeimmistä toiminnoista. Käyttöliittymässä kannattaa miettiä käytettävyyttä, joka on yksi tärkeä osa sovellusta. Käytettävyys on asiana todella laaja, joten tässä tekstissä vain raapaistaan pintaa. Jos käyttäjän ei ole sallittua kaikkina aikoina käyttää kaikkia osia, kannattaa miettiä miten käyttäjää informoidaan ettei osa sovelluksesta ole käytössä. Pelkkä sovelluksen osan häviäminen käyttöliittymästä voi hämmentää käyttäjää, jos käyttäjällä joskus on kuitenkin mahdollisuus käyttää kyseistä osaa. Tai sama käyttäjä voi olla useassa eri roolissa sovelluksen käytössä. Käyttöliittymä suunnitelmassa voidaan myös kertoa kuka kyseistä osaa voi käyttää - esimerkiksi: -etusivu (asiakas & kirjasto) -asiakas +asiakkaan haku (asiakas & kirjasto) +asiakkaan tietojen katselu (asiakas & kirjasto) +asiakkaan muokkaus (kirjasto) +asiakkaan poisto (kirjasto) +asiakkaan luonti (kirjasto) +asiakkaan lainojen katselu (asiakas & kirjasto) +asiakkaan lainojen palautuksen (kirjasto) -teokset +teoksen haku (asiakas & kirjasto) +teoksen tietojen katselu (asiakas & kirjasto) +teoksen muokkaus (kirjasto) +teoksen poisto (kirjasto) +teoksen luonti (kirjasto) +teoksen lainaus (kirjasto) 3.2. Tietovaraston suunnitteluJos sovelluksen varastoitava ja haettava tietoa, kannattaa suunnitella mihin tieto tallennetaan esim. tietokantaan tai tiedostojärjestelmään ja miten tieto sinne tallennetaan esim. tietokannan kuvaus tai tiedostojen sijainnin ja sisällön kuvaus. Ristiriitojen välttämiseksi tietovaraston sisällössä vältettävä tiedon säilyttämistä kahdessa paikassa. Tietovaraston suunnittelussa yksinkertaisuus on kaunista ja helpottaa ylläpitoa. Esimerkki tietokannan rakenteesta - huomaa että tämä kannattaa jo tehdä englanniksi, jotta ohjelmistossa voidaan käyttää samoja termejä: -user +name +login (primary key) +password +contact address +role -item +name (primary key) +creator +type +units -type +name (primary key) +loan period -unit +item (foreign key) +user (foreign key) +start date +end date 3.3. Sovelluksen suunnitteluSuunnitelmassa kannattaa tuottaa vähintään ylemmän tason suunnitelma miten sovellus aiotaan toteuttaa mm. millä ohjelmointikielellä. Suunnittelussa kannattaa pilkkoa kokonaisuus osiin, joista kannattaa ensin suunnitella yleiskäyttöisiä osia ja lopuksi ohjelmistokohtaiset osat. Jos sovellus pilkotaan kerroksiin, kannattaa tämä kuvata suunnittelu dokumentaatioon. Kerroksia voi olla esim. tietokanta kerros, logiikka kerros ja käyttöliittymä kerros. Suunnittelussa voidaan ottaa kantaa, että nimeämiseen esim. toteutus kerrokset, asennuspaketit, asennuspolut, versiointi yms. Suunnittelussa voidaan mahdollisesti ottaa kantaa lähdekoodin ulkoasuun, sovelluskehittimeen jolla lähdekoodi tehdään, lähdekoodin versiohallintaan, lähdekoodiin kääntämiseen ajattavaksi ohjelmaksi. Esimerkki suunnittelun tuloksesta: -Toteutus tehdään J2EE (=Javan Enterprise Edition) 1.5 versiolla -Sovellusta ajetaan JBoss-sovelluspalvelimen 3.2 versiolla -Tietokantana käytetään Derbyn versiota 10.1 -Käyttöliittymä toteutetaan XHTML 1.0 standardin mukaan -Käyttöliittymä toimii Mozilla 1.0 selaimella -Sovelluskehittimenä käytetään Eclipsen versiota 1.3 -Versiohallintaan käytetään CVS:ssää -Versiohallinnan päähaarassa pitää olla testattu ja toimiva ohjelma -Versiohallintaan luodaan sivuhaara library-example, johon kehitystyötehdään -Sovelluksen nimi on library-example -Sovellus paketoidaan example.library-pakettiin +example.library.db-paketti sisältää tietokanta toteutuksen +example.library.logic-paketti sisältää sovellus logiikan +example.library.ui-paketti sisältää käyttöliittymän -Sovellus kirjoittaa logia java.util.logging.Logger-luokalla +Virheet logittaa käyttöliittymä taso, alemmat tasot heittävät MyException +Severe-tasoa käytetään virheestä, jolloin ei voida jatkaa esim. tietokanta rikki +Warning-tasoa käytetään virheestä, joka johtuu esim. käyttäjän syötteestä +Info-tasoa käytetään käyttäjän kirjautuessa sisään ja ulos +Fine-tasoa käytetään käyttäjän vaihtessa sivua +Finer-tasolla kirjoitetaan logiikan pääkohdat ja tietokanta haut +Finest-tasolla kirjoitetaan muut mahdolliset tiedot 4. ToteutusToteutus sisältää lähdekoodin, lähdekoodin dokumentoinnin ja sovelluksen yksikkötestit. Lähdekoodin keskeisiä asiota on mm. nimeäminen, selkeys, luettavuus, yksikkötestattavuus. Yksikkötestit sisältävät metodien testaamisen ilman käyttöliittymää tai IO-rajapintoja esim. tietokanta yhteyttä. Yksikkötestit kannattaa automatisoida, jotta jokaisen muutoksen jälkeen voi varmistua ohjelmiston toimivuudesta. Yksikkötesteistä on myös tärkeää saada dokumentti, jotta testaus vaiheessa tiedetään mitä kaikkea on testattu. Kätevin tapa dokumentoida yksikkötestit Javassa on käyttää standardeja Javadoc merkintöjä. Yksikkötestien tekeminen edesauttaa koodin selkeyttä, koska se pakottaa jakamaan koodin pieniin osiin. Selkeyttä lisää se, ettei samaa koodia kopioida useisiin paikkoihin vain keskitetään yhteen. Tämä helpottaa ohjelmiston ylläpidettävyyttä ja vikojen korjaamista. Hyvä nimeäminen ja luettavuus helpottaa koodin sisäistämistä jälkikäteen. Se auttaa tekijää itseään palamaan astialla pitkän ajan jälkeen. Tärkeässä roolissa on virheiden käsittely, joka kannattaa erottaa varsinaisesti sovelluskoodista. Kätevimmin Javassa tämä tapahtuu tekemällä omia poikkeusluokkia. Jos tälläisiä poikkeuksia esiintyy ohjelmaa ajattaessa, voidaan vika paikantaa suoraan oikeaan paikkaan eikä tarvitse epäillä esim. sovelluspalvelvinta. Poikkeuksien perusperiaate on heittää ne mahdollisimman aikaisin ja ottaa kiinni mahdollisimman. Poikkeuksesta kannattaa tehdä ajonaikainen, jos ylemmällä tasolla ei voida tehdä poikkeukselle mitään esim. tietokanta yhteys on poikki. 5. TestausTestaus on vaativa ja laaja kokonaisuus, jota helposti väheksytään. Karkeasti testaaminen voidaan jakaa suorituskyky ja toiminnalliseen testaamiseen. Testauksen perustana toimii vaatimukset ja niitä täydentävät yksikkötestit. Testaamisen automatisointia kannattaa harkita, mutta monesti manuaalisesti testaaminen on nopeampaa lyhyessä juoksussa. Automaattitestauksen hyödyt tulevat esille vasta, kun sovelluksesta tehdään useita versioita ja samoja testitapauksia joudutaan ajamaan useita kertoja läpi eli rekressiotestaamaan. Testausta voidaan tehdä hyvin monella tasolla: yksikkötestauksesta, integraationtestauksen, järjestelmätestatuksen kautta aina hyväksyntätestatukseen. Testauksen yhteydessä sovitaan miten virheiden korjaukset aikataulutetaan. Jos virheitä on paljon, joudutaan kategorioiden sisällä sopimaan erikseen korjausjärjestys. Virheet voidaan esimerkiksi jakaa seuraaviin kategorioihin helpottamaan korjausjärjestystä:
6. KäyttöönottoKäyttöönotto vaatii erityistä suunnittelua, jos kyse on toiminnassa olevan sovelluksen korvaamisesta uudella. Tällöin on syytä ottaa huomioon nykyiset käyttäjät varsin tarkkaan mietittäessä ohjelmiston korvaamisen ohjeistusta ja ajankohtaa. Jos korvataan vanha sovellus, pitää ottaa huomioon kuinka vanhaa sovellusta tuetaan ylimenokauden ajan, kun molemmat sovellukset ovat rinnakkain käytössä. Ideaalitilanne olisi, jos ylimenokautta ei olisi ollenkaan. 7. YlläpitoYksikään sovellus ei ole ikinä täysin valmis, koska elämme muuttuvassa maailmassa. Monikohan erehtyi aikanaan luulemaan, ettei vuotta 2000 tulisi ikinä =) Tai että Suomessa olisi markka valuuttana ikuisesti =) Reaalimaailman muutoksista johtuen ylläpito kannattaa ottaa huomioon jo ohjelmiston määrittelyvaiheessa - muista vaiheista puhumattakaan. Kuinka paljon ylläpitoa helpottaa, jos ohjelmisto on laadukkaasti tehty alusta loppuun. |