OMT - Object Modeling Technique

Ohjelmistotekniikan seminaari

31.10.1996

Mika Toivola



1. Johdanto

Tämä html -dokumentti perustuu Jyväskylän yliopiston ohjelmistotekniikan seminaarissa 31.10.1996 pidettyyn esitykseen OMT - Object Modeling Technique. Esityksen piti ja tämän materiaalin kokosi Jyväskylän yliopiston tietotekniikan opiskelija Mika Toivola.

Tämä seminaarityö esittelee laaja-alaisessa ohjelmistotuotannossa käytössä olevaa olio-ohjelmoinnin suunnittelumenetelmää OMT:tä.

Kappaleissa 2 - 6 esitellään OMT-menetelmänä, sen eri vaiheet, mallit ja niiden notaatiot. Luvuissa painotetaan, ettei menetelmä ole vain jokin irrallinen suunnittelumenetelmä vailla käytännön sovelluksia. Näin ollen, erityisesti kuudennessa luvussa, käsittellään menetelmän rajapintoja varsinaiseen toteutukseen.

Seitsemännessa luvussa esitellään lyhyesti yksi OMT-menetelmään perustuva CASE -työkalu Select OMT 5.0. Kahdeksannessa luvussa esitellään kehitteillä oleva suunnittelumenetelmä UML, joka tulee olemaan varsin todennäköinen OMT:n seuraaja.

Seitsemännen ja kahdeksannen lukujen lähdemateriaalina on käytetty varsin subjektiivista materiaalia, joten suosittelen niiden lukemisessa hieman kriittisempää asennetta. Tämän materiaalin lukijalla oletetaan olevan perustiedot olio-ohjelmoinnista. Ainakin ominaisuuksien ja toimintojen yhteenliittämisen, periytymisen, olioluokkien ja olioiden käsitteiden tulisi olla hallussa.


2. OMT suunnittelumenetelmänä

Olioajatteluun perustuvassa määrittelyssä ja suunnittelussa pyritään yhdistämään tieto- ja toimintakeskeinen ajattelu yhdeksi kokonaisuudeksi. Vanhoihin menetelmiin verrattuna siinä tulisi uudelleenkäytön korostua. Oliolähestymistapa pyrkii siirtämään yrityksen liiketoiminnan käsitteet sellaisenaan tietojärjestelmiin, jolloin tietojärjestelmät vastaavat paremmin käyttäjien ja yritysten tarpeita.

Object Modeling Technique (OMT) eli olioiden mallintamistekniikka on ohjelmointikielestä riippumaton graafinen merkitsemistapa. Se kehitettiin osaksi oliolähestymistapaa ohjelmistojen suunnitteluun. OMT-menetelmä, kuten muutkin suunnittelumenetelmät, on tarkoitettu organisoituun laaja-alaiseen ohjelmistotuotantoon. Se tukee ohjelmiston koko elinkaarta lähtien ongelman määrittelystä, vaatimusanalyysistä edeten suunnittelun ja toteutuksen kautta ylläpitoon. OMT-menetelmän avulla ohjelmiston suunnittelijat voivat visualisoida ideansa toisillensa ja myös asiakkaan kanssa kommunikointi helpottuu.

OMT-menetelmä koostuu useista vaiheista jotka ovat määrittely (analysis), systeemisuunnittelu (system design), oliosuunnittelu (object design) ja toteutus (implementation). Toteutusvaihe sijoittuu varsinaisen ohjelmoinnin ja suunnittelun välimaastoon. Täten useimmiten puhutaankin menetelmän koostuvan kolmesta ensin mainitusta vaiheesta, joista määrittelyvaiheen voidaan katsoa olevan tärkein ja käytetyin. Määrittelyvaiheessa ja eritoten siinä luotavassa oliomallissa onkin tehokkain osa OMT -suunnittelumenetelmää.

2.1 Historiaa

OMT -suunnittelumenetelmän kehitettiin New York:issa, General Electrics Research:issä ja Schenectadyn tutkimusosastossa. Pääsuunnittelijana toimi Tohtori James Rumbaugh, joka alunperin kehitti DSM-oliokielen (samoihin aikoihin kun C++ kehitettiin). Hän kehitteli yhdessä kollegojensa kanssa tälle kielelle notaation (noin 1985). Sen käsitteistä hän kehitteli OMT:n, jota hän kuvasi suositussa kirjassaan "Object Modeling and Design, 1991". Kirjan ilmestymisen jälkeen OMT:stä tuli laajalti käytetty suunnittelumenetelmä kaikkialla mailmassa. Lokakuussa 1994 Rumbaugh siirtyi Rational Software Corporationin organisaatioon suunnittelemaan OMT:n ilmeistä seuraajaa UML:ää (Unified Modeling Language), RUMB96.

2.2 Vaiheet

Määrittelyvaiheen tuloksena saadaan dokumentti, joka kuvaa täsmällisesti mitä järjestelmä tekee. Se ei kuitenkaan kuvaa sitä, miten se sen tekee. Olio-ohjelmointia tuntemattoman tulee kyetä ymmärtämään määrittelyvaiheen tuotoksia. Dokumenteissä ei saa esiintyä toteutukseen liittyviä rakenteita (esim. tietorakenteita).

Systeemisuunnittelussa tehdään yleisiä päätöksiä systeemin arkkitehtuurista. Systeemisuunnitteluvaiheen aikana kohdesysteemi pilkotaan osiin ja päätetään, miten nämä osat soveltuvat valittuun arkkitehtuuriin. Systeemisuunnittelijan tulee mm. miettiä, mitä tehtäviä optimoidaan.

Oliosuunnitteluvaiheessa lisätään malliin toteutukseen liittyviä seikkoja, kuten tietorakenteita, algoritmeja ja tehokkuusnäkemyksiä.

Toteutusvaiheessa olioluokat ja suhteet muutetaan valitulle olio-ohjelmointikielelle (tai muulle vastaavalle välineelle). Ohjelmoinnin tulisi tämän jälkeen olla lähes triviaali tehtävä, sillä tärkeimmät päätökset on tehty suunnittelun aikana.


3. Määrittelyvaihe

3.1 Ongelman määrittely

Määrittelyvaihe alkaa ongelman hahmottelulla, johon osallistuvat sekä asiakkaat että mahdollisesti kehittäjät. Tässä vaiheessa ei tuotettu dokumentti ole välttämättä kovin tarkka, vaan se tarkentuu analyysin edetessä. Tarkoituksena on kuvata lyhyesti, mitä rakennettava ohjelmisto tulee tekemään ja mitä muita mahdollisia rajoittavia tekijöitä on olemassa.

Määrittelyvaihe ei ole mekaaninen prosessi. Useasti tarpeellinen tieto ei ole saatavilla, ja vielä useammin määrittelyvaiheen alussa ei tiedetä, mikä on tarpeellista tietoa ja mikä ei. Määrittelytyötä tekevien suunnittelijoiden on keskusteltava useiden osapuolten kanssa ja mahdollisesti tutustuttava vanhoihin dokumentteihin sekä muuhun kirjallisuuteen aivan kuten perinteisessä suunnittelumenetelmässä.

3.2 Ongelman mallinnus

OMT:ssä määrittelyvaihe koostuu kolmesta erillisestä mallista, jotka ovat oliomalli, dynaaminen malli ja toiminnallinen malli. Jokainen malli antaa erilaisen näkemyksen suunniteltavaan järjestelmään. Vaikka mallit ovat hyvin erilaisia jopa logiikaltaan, ne täydentävät toisiaan. Mallien välillä tulee luonnollisesti olla yhteyksiä, joita käsitellään tarkemmin luvussa 3.6.

Oliomalli on malleista tärkein, kuten jo aikaisemmin mainittiin. Siinä kuvataan olioluokat ja attribuutit sekä olioluokkien väliset suhteet. Oliomallin tarkoituksena on kuvata todellisuutta puhumalla mallinnettavan maailman omilla termeillä eikä tietoteknisillä slangisanoilla.

Dynaamisen mallin tarkoitus on mallintaa järjestelmän käyttäytymistä ajan ja muiden toimintojen suhteen. Mallinnus tehdään tilakaavioilla.

Toiminnallinen malli kuvaa, mitä järjestelmä tekee välittämättä milloin tai miten tehtävä suoritetaan. Tarkoituksena on kuvata järjestelmään tulevia syötteitä, miten niitä käsitellään ja mitä tulosteita järjestelmästä saadaan.

3.3 Oliomalli

Oliomalli kuvaa järjestelmän olioluokkia ja niiden välisiä suhteita. Kuvassa 1 on esimerkki oliomallista.

Kuva 1. Pankkiautomaatin oliomalli. Attribuutit ja metodit on jätetty luokista pois mallin yksinkertaistamiseksi.

3.3.1 Oliomallin notaatio

Luokat kuvataan OMT-menetelmässä kuvan 2 kolmiosaisella suorakaiteella, jossa yläosassa on luokan nimi, keskellä attribuutit ja alaosassa olion tarjoamat palvelut (metodit). Oliot kuvataan (tarvittaessa) pyöristettyinä suorakaiteina.

Kuva 2. Olioluokka.
Assosiaatio kuvaa olioiden välistä pysyvää linkkiä (kuva 3).

Kuva 3. Kahden luokan välinen yhteys.

Kuvassa 4 on esitetty erilaisia assosiaatioiden tyyppejä.

Kuva 4. Assosiaatioiden tyyppejä.

Tarkennettu assosiaatio (kuva 5) kuvaa monenkeskistä suhdetta, joka tietyn attribuutin suhteen on yksikäsitteinen. Yhden suhde moneen -yhteydet voidaan tarkentaa jonkin ominaisuuden perusteella.

Kuva 5. Tarkennettu assosiaatio.

Monenväliset assosiaatiot (kuva 6) kokoavat useamman luokan yhteen. Jos ko. assosiaatio puretaan kahdenvälisiksi assosiaatioiksi, menetetään tietoa. Esimerkissä tietty henkilö työskentelee tietyssä projektissa tietyllä kielellä.

Kuva 6. Monenvälinen assosiaatio.

Aggregaatti (koostuminen, kuva 7) kuvaa olioiden välistä pysyvää yhteyttä.

Kuva 7. Aggregaatti eli koostuminen.

Linkkiattribuutit (kuva 8) ovat atribuutteja joita ei voi sijoittaa minkään luokan attribuuteiksi.

Kuva 8. Työsuhde linkkiattribuuttina.

Kuvioiden periytymisrakenne esitetään kuvan 9 mukaisella tavalla.

Kuva 9. Kuvioiden periytymisrakenne.

Moniperinnässä (kuva 10) musta kolmio tarkoittaa tilannetta, jossa alaluokat eivät ole erillisiä vaan päällekäisiä ainakin jonkun ominaisuuden suhteen (periytyvät samasta esi-isästä).

Kuva 10. Moniperintä.

3.3.2 Oliomallin muodostamisen vaiheet

Tunnista olioluokat. Listaa kaikki kandidaatti olioluokat tehtävän kuvauksesta. Tee tämä alleviivaamalla kaikki substantiivit tekstistä. Mieti löytyykö muita.

Hylkää tarpeettomat ja väärät luokat seuraavien kriteerien mukaan: Synonyymit luokat - jos kaksi luokkaa kuvaavat samaa informaatiota, kuvaavin tulee säilyttää, epäolennaiset luokat - jos luokalla on vain vähäinen merkitys tehtävässä, se tulee poistaa, epämääräiset luokat - luokat, joilla on epäselvät rajat, tulee poistaa (esim. päivitys), attribuutit - nimet, jotka pääsääntöisesti kuvaavat yksittäisiä olioita, tulee määritellä kyseisen olion attribuutiksi, operaatiot - jos nimi kuvaa operaatiota, jota toiset oliot käyttävät "omin luvin", se ei ole luokka, roolit - luokalla tulee olla itsenäinen luonne, joten sillä ei saa olla assosiaatiota kuvaava rooli, toimeenpanoon liittyvät rakenteet - rakenteet, jotka ovat reaalimaailmaan kuulumattomia, tulee karsia analyysimallista.

Perusta käsiteluettelo. Kirjoita kappale kustakin luokasta, jossa kuvaat sitä. Kuvaa luokkaa kyseisen tehtävän näkökannalta. Sisällytä luetteloon luokkaa ja sen käyttöä koskevat oletukset ja rajoitukset. Attribuutit, assosiaatiot ja operaatiot kuvataan käsiteluettelossa.

Tunnista yhteydet olioluokkien välillä. Assosiaatiot ovat usein luokkien välisiä yhteyksiä kuvaavia verbejä. Näihin kuuluvat paikat, toiminnot, kanssakäyminen, omistaminen tai jonkin ehdon täyttäminen. Lopuksi karsi turhat assosiaatiot.

Tunnista olioiden ja yhteyksien attribuutit. Attribuutit kuvaavat olioiden ominaisuuksia.

Attribuuttien arvot ilmenevät useasti tekstissä adjektiiveinä (auto on punainen) tai genetiiveihin liittyvinä substantiiveina (henkilön ikä). Oliomalliin attribuuteiksi ei pidä valita itsenäisiä olioita eikä linkkiattribuutteja. Oliomalliin tulee ottaa mukaan vain luokkaa havainnollistavat attribuutit.

Järjestä oliomalli käyttäen periytymistä. Periytymisellä tarkoitetaan tilannetta, jossa jokin luokka perii kaikki jonkun toisen luokan ominaisuudet. Periytymishierarkiat löytyvät esimerkiksi tutkimalla, ovatko olioluokat jonkin ylemmän asian, olion tai tilanteen erikoistapauksia. Periytymisrakenteiden muodostamisessa kannattaa olla varuillaan. Periytä vain niitä olioluokkia, jotka loogisesti tuntuvat periytyvän toisistaan.

Tarkista, että kaikki yleisimmät kyselyt saadaan toteutettua. Käy läpi oliomallin polkuja (linkkejä) nähdäksesi saadaanko järkeviä tuloksia. Kun halutaan yksikäsitteinen arvo, onko polkua sen saamiseksi? Onko relaatiosta "monta" tarvittaessa mahdollisuus yksikäsitteisen olion hakemiseen? Mieti muita tarpeellisia kysymyksiä, joita ei voi mallista toteuttaa. Tällöin mallista puuttuu informaatiota.

Testaa mallia. Onko kaikki tarvittavat käsitteet mukana? Löytyykö kaikkiin yleisimpiin kysymyksiin vastaukset? Löytyykö toistoa? Ovatko yhteydet kohdemaailmaan kunnossa? Onko periytyminen ja koostamisrakenteet kunnossa?

Ryhmittele luokat moduleiksi. Liian suuren oliomallin hallinta on hankalaa. Oliomalli on syytä pilkkoa moduleihin, jos kaavio ei mahdu A4:lle. Kaavioiden yhteiset luokat tulee kopioida rajapintaluokiksi eri kaavioihin BAKK96.

3.4 Dynaaminen malli

Oliomalli kuvaa olioiden pysyviä suhteita toisiinsa. Ajan mittaan oliot pyytävät palveluita toisiltaan ja aiheuttavat siten olioiden siirtymistä tilasta toiseen. Olion toimintopyyntö voidaan ymmärtää toiseen olioon saapuvana tapahtumana (event). Olion vastaus tapahtumaan riippuu olion senhetkisestä tilasta ja luonnollisesti tapahtumasta itsestään. Olio voi reagoida tapahtumaan vaikka omaa tilaa muuttamalla tai lähettämällä toiselle oliolle tapahtuman. Tapahtumia ovat esimerkiksi käyttäjän hiiren näpäytys ja laivan lähtö Tukholmaan.

Edellä kuvatun tilanteen voi mallintaa hyvin tilasiirtymäkaaviolla. Tilasiirtymäkaavio on tilojen ja tapahtumien muodostama verkko. Dynaaminen malli muodostuu useista tilasiirtymäkaavioista. Tilasiirtymäkaavio muodostetaan luokille, joilla on riittävän monimutkainen vuorovaikutus suhde toisten luokkien kanssa sekä luokille, jotka ovat reaaliaika riippuvaisia.

Jos suunniteltava ohjelmisto on pelkästään tietoja säilövä (tietokantatyyppinen), ei dynaminen mallinnus ole välttämättä tarpeen. Toisaalta järjestelmän operaatioiden hahmottelussa tilasiirtymäkaavioista on runsaasti hyötyä. Dynaaminen mallinnus on tarpeen erityisesti vuorovaikutteisissa reaaliaikaisissa sovelluksissa.

3.4.1 Dynaamisen mallin rakentaminen

Tunnista tyypilliset vuorovaikutusketjut. Esimerkki pankkiautomaatin vuorovaikutusketjusta:
- Pankkiautomaatti pyytää käyttäjää syöttämään kortin, jolloin käyttäjä syöttää kortin.
- Pankkiautomaatti lukee kortin ja lukee sen sarjanumeron.
- Pankkiautomaatti pyytää käyttäjää antamaan salasanan, jolloin käyttäjä syöttää salasanan.
- Pankkiautomaatti tarkistaa (linjoja pitkin), että salasana on oikea. Jos salasana on väärä, ilmoitetaan siitä ja kortti palautetaan käyttäjälle.
- Pankkiautomaatti pyytää nostettavan summan.
- Pankkiautomaatti tarkistaa (linjoja pitkin), onko tilillä katetta. Jos on niin automaatti pyytää pankin keskuskonetta suorittamaan tapahtuman. Jos tilillä ei ole katetta, kortti palautetaan käyttäjälle.
- Pankkiautomaatti antaa kortin takaisin. Käyttäjä ottaa kortin.
- Pankkiautomaatti antaa kuitin ja rahat. Käyttäjä ottaa kuitin ja rahat.
- Pankkiautomaatti pyytää käyttäjää syöttämään kortin.

Tunnista olioiden väliset tapahtumat. Tutki vuorovaikutusketjua ja tunnista tapahtumat, joita ovat signaalit syötteet, tulosteet, keskeytykset yms. Esimerkiksi "Anna salasana" on pankkiautomaatilta käyttäjälle kulkeva tapahtuma. "Salasanan syöttö" on taas tapahtuma käyttäjältä pankkiautomaatille.

Rakenna skenaariot, jotka ovat vuorovaikutusketjujen formaali esitystapa. Skenaarioon merkitään pystyviivoin ne luokat, joiden välissä vuorovaikutusta halutaan tutkia. Tapahtumat kulkevat näiden pystyviivojen välillä olioluokalta toiselle.

Kuva 11. Pankkiautomaatin skenaario.

Muodosta tilasiirtymäkaaviot, joissa tapahtumat ovat olioiden toisilleen lähettämiä toimintapyyntöjä. Vastaanottava olio reagoi toiminta pyyntöihin nykyisen tilansa perusteella suorittaen tietyn toiminnon ja mahdollisesti vaihtaen nykyisen tilansa toiseksi. Tila puolestaan on olion attribuuttien ja sen linkkien (muihin olioihin) summan abstraktio eli olion tilaa kuvaa sen attribuutit ja linkit muihin olioihin. Tilasiirtymäkaaviot tehdään periaatteessa kaikille oliomallin luokille, mutta joidenkin luokkien tilasiirtymäkaaviot voivat kuitenkin olla triviaaleja. Triviaaleissa pelkkien tapahtumien kirjaaminen riittää.

Valitse luokka ja kirjaa ylös kaikki luokkaan tulevat ja sieltä lähtevät tapahtumat (löydät nämä skenaariosta). Ryhmittele kaikki samantyyppiset tapahtumat saman tapahtumaluokan alle. Esimerkiksi laivan lähtö Tallinnaan on eri tapahtuma kuin laivan lähtö Tukholmaan, mutta kyseessä on silti samaan luokkaan kuuluvat tapahtumat. Muodosta tapahtumien perusteella tilasiirtymäkaavio. Tilasiirtymäkaavio on valmis, kun se kattaa kaikki mahdolliset vaihtoehdot. "Mitä jos" -kysymys kannattaa esittää useasti.

Kuva 12. Pankkiautomaatti -luokan (kts. kuva1) tilasiirtymäkaavio. Huom. laajempi kuin vastaava skenaario (kts. kuva 11).

3.5 Toiminnallinen malli

Toiminnallinen eli funktionaalinen malli on OMT-mallinnuksen kolmas jalka. Funktionaalinen malli kertoo, mitä tapahtuu. Dynaaminen malli kertoo, milloin tapahtuu.Oliomalli kertoo mille ne tapahtuu. Funktionaalinen malli kuvataan tietovuokaaviotekniikalla (kuva 14). Tietovuokaavitekniikassa käytetään kuvan 13 symboleja.

Kuva 13. Tietovuokaavion notaatio.

Kuva 14. Pankkiautomaatin tietovuokaavio.

Tietovuokaavioiden tarkentaminen tapahtuu periaatteessa samaan tapaan kuin rakenteellisessa mallinnuksessa, huomioiden oliomalli tietovarastojen käsittelyssä. Prosessit voidaan kuvata vielä tarkemmin sanallisesti tai pseudokoodilla (tms.).

3.6 Mallien väliset yhteydet

3.6.1 Olio- ja dynaaminen malli

Dynaaminen malli määrittelee kunkin oliomallin luokan sallitun tilamuutosjärjestyksen. Dynaamisen mallin tilat voidaan liittää luokan attribuutteihin ja tapahtumat voidaan käsittää oliomallin metodeina (operation).

Oliomallin yleistämisen (generalisation), koostumisen (aggregation) ja perinnän (inheritance) käsitteet pätevät myös dynaamisessa mallissa.

Jokainen olion alatila rajoittaa arvoja joita oliolla voi olla. Yleistämisessä rajoitetaan olion tilat kokoelmana kaikista mahdollisista luokan tiloista. Kun on olemassa perittyjä erovaisuuksia olioiden välillä, ne mallinnetaan erilaisina luokkina. Kun erot ovat väliaikaisia, ne mallinnetaan saman luokan erillaisina tiloina.

Aggregaatti eli yhdistetty tila on useamman kuin yhden alatilan kooste. Aggregaatti on olemassa kahdella tasolla: olioiden kooste (yhdistetty tila on osien yksittäisten tilojen yhdiste) ja kooste oliossa (attribuuttien ryhmät määrittävät yhdistetyn tilan).

Tapahtumien ja tilojen hierarkiat on mahdollista piirtää. Tapahtumat perivät vanhempansa attribuutit ja tilat perivät mahdolliset tilamuutokset. Dynaamisen mallin luokat perivät myös omat yläluokkansa.

3.6.2 Olio- ja funktionaalinen malli

Kaikki neljä funktionaalisen mallin komponenttia voidaan liittää oliomalliin.

Funktionaalisesta mallista näemme, että prosessit täytyy toteuttaa olioiden metodeilla. Mallista näkee, mihin olioihin prosessit ovat liittyneet. Useimmiten prosessin tarkoituksena (palvelu) on yhden tuloksen saanti tai syöttö. Muut prosessin välittämät arvot ovat parametreja (hankkijat). Nämä asiakas-hankkija -suhteet luovat työkalut kahden luokan väliseen kommunikointiin.

Ulkoiset oliot ovat oliomallin olioita.

Tietovarastot ovat myös oliomallin olioita tai niiden attribuutteja.

Tietovuot ovat oliomallin arvoja. Tietovuot ulkoiselle oliolle tai oliolta kuvaavat olion omia tai olion käyttämiä operaatioita. Tietovuot ulkoiselta oliolle tai oliolta kuvaavat kyselyitä tai päivityksiä.

3.6.3 Dynaaminen ja funktionaalinen malli

Näiden kahden mallin suhde on seuraavanlainen (kuten aikaisemmin mainittiin). Dynaaminen malli kertoo, milloin operaatiot toteutetaan. Funktionaalinen malli kertoo, kuinka ne toteutetaan ja mitä argumenttejä tarvitaan. Ulkoisten olioiden ja tietovarastojen operaatioista löytyy eroavaisuuksia näiden kahden mallin välillä. Koska ulkoiset oliot ovat aktiivisia olioita, dynaamisen mallin täytyy mallintaa (tarkentaa), milloin ne "ovat toiminnassa". Tietovarastot ovat passiivisia olioita, niille voi ainoastaan tehdä kyselyitä ja päivityksiä. Niitä ei siis dynaamisessa mallissa tarvitsekaan mallintaa.


4. Systeemisuunnitteluvaihe

Määrittelyn ja suunnittelun raja on häilyvä. Mitään lopullista ratkaisua tähän rajanvetoon tuskin on olemassa. Tässä materiaalissa esitetään eräs näkemys, joka perustuu OMT -kirjallisuuteen, käytössä oleviin oliomenetelmiin ja rakenteisten sovellusten kehittämisestä saatuihin kokemuksiin ohjelmisto projektien luonteesta.

4.1 Käyttöliittymäluokkien lisäys

Yksinkertaisuuden vuoksi tässä materiaalissa tutustutaan SmallTalk -80 kielestä peräisin olevaan käyttöliittymien rakentamismalliin eli ns. MVC-malliin. Mallissa erotetaan käyttöliittymäoliot loogisesta oliomallista. MVC-malli jakautuu Model-, View- ja Controller-osaan.

Perinteisesti Model-osa koostuu ohjelman säilyvistä olioista. Mallilla ei ole visuaalisia ominaisuuksia, ts. malliin ei liity käyttöliittymäkoodia.

View-osa näyttää olioiden tilan käytttäjälle. Controller-osa yhdistää Model- ja View-osat. Controller-osa päivittää View-osaa Model-osan mukaisesti. View-osa tarjoaa käyttöliittymän käsittelyyn liittyvät toiminnot, kuten ikkunoiden luonnin ja tuhoamisen. Useasti View -osan päivitys tapahtuu Show()-tyyppisillä viesteillä. Joko View-osa pyytää tarvitsemansa tiedot Model-osalta tai Controller-osa välittää arvot View-osalle.

Kaikessa yksinkertaisuudessaan graafinen käyttöliittymä suunnitellaan MVC-mallilla seuraavasti:
- Model-osa saadaan OMT:n oliomallista.
- Suunnittele View-osa (erillinen käyttöliittymä suunnitelma).
- Suunnittele Controller-osa, joka yhdistää edelliset.

Esimerkkinä käytetään Windowsin kalenteri -ohjelmaa, jota mallinnetaan kuvassa 15. Kalenteriohjelmassa on pääikkuna sekä useita dialogeja kuten Open, Save, Print Setup ja Page Setup -dialogit.

Kuva 15. Kalenteri käyttöliittymäluokkineen.

4.2 Systeemisuunnittelu

Kun ongelma on analysoitu, voidaan miettiä, miten sitä lähestytään tekniseltä kannalta. Systeemisuunnittelussa päätetään miten järjestelmä jaetaan alijärjestelmiin, millaisia järjestelmäarkkitehtuuria käytetään, millaiset tietoliikenneratkaisut ovat käytettävissä, miten tiedot meinataan tallettaa pysyvästi jne.

Systeemisuunnittelun vaiheita ovat järjestelmäarkkitehtuurin määrittely (asikas-palvelin, rinnakkaisprosessori, NT, Unix, ...) ja ohjelmalohkojen määrittely, kaupalliset kirjastot, omat kirjastot, ...

4.3 Oliomallin tarkennus operaatioilla

Dynaamisen ja toiminnallisen mallin pohjalta täydennetään oliomalli operaatioilla. Periaatteessa jokaiseen olion saamaan tapahtumaan voidaan liittää operaatio. Tilasiirtymäkaaviossa (kts. kuva 12) jokaisen siirtymän jälkeen suoritettu toiminto riippuu sekä tapahtumasta että objektin tilasta. Jos sama tapahtuma voidaan ottaa vastaan useassa eri tilassa, täytyy operaation toteutuksessa olla toiminnot jokaista tilaa varten.

Olion lähettämä tapahtuma on yleensä jonkin toisen olion operaatio. Tapahtumat usein esiintyvät pareittain, jolloin ensimmäinen tapahtuma aktivoi toiminnon ja toinen tapahtuma palauttaa toiminnon tuloksen.

Tilan vaihdon aikaansaava tapahtuma voi laajentua jopa yhdeksi funktionaalisen mallin tietovuokaavioksi (kts kuva 14). Suunnittelijan täytyy muuttaa tietovuokaaviot sarjallisiksi olioiden suorittamiksi algoritmeiksi.

Prosessin kohdeolio määritetään seuraavasti:
- Jos prosessi ottaa arvon syötevuosta, on syötevuo prosessin kohdeolio.
- Jos prosessilla on samantyyppiset syöte- ja tulosvuot, tällöin jompikumpi vuoista on kohdeolio.
- Jos prosessi kokoaa useista syötevuoista yhden tulosvuon, on kyseessä tulosvuon kohdeolion luoja (constructor).


5. Oliosuunnitteluvaihe

Oliosuunnitteluvaiheessa lisätään malliin toteutukseen liittyviä seikkoja, kuten tietorakenteita, algoritmeja ja tehokkuusnäkemyksiä. Suunnittelemalla oliot ennalta parannetaan ohjelmiston laatua.

Usein tämä vaihe jätetään väliin ja hoidetaan koodauksen yhteydessä, jolloin bug'it ja ovat vaarana. Tehokkain ja varmin ratkaisu jää usein koodatessa löytämättä. Tämän vaiheen väliinjättämisen syynä on usein lähinnä OMT-sovellusten tuki, joka loppuu useimmiten määrittely-suunnitteluvaiheen rajapinnoille.

Tämän vaiheen ongelmien tarkastelu on hyvin sovelluskohtaista, joten tämän kohdan syvempi käsittely sivuutetaan.


6. Toteutusvaihe

Tavoitteena on muuttaa oliomalli tarkoiksi luokkakuvauksiksi eli selvittää, miten toteutetaan luokat, aggregaatit ja assosiaatiot valitulla olio-ohjelmointikielellä. Tässä yhteydessä määritellään luokan jäsenmuuttujat ja metodit parametrityyppeineen ja paluuarvoineen.

Tässä materiaalissa keskitytään oliomallin toteutukseen C++-kielellä. OMT-menetelmään "sisältyvän" toteutusjakson päätteksi pitäisi kaikista luokista olla käytettävissä C++-otsikkotiedostot ennen varsinaista koodamisen aloittamista.

6.1 Oliomalli C++ -kielellä

6.1.1 Luokat koodina

    class keskusyksikko {
        private:
            int m_tunnus;
            int m_prosessori;
            int m_kellotaajuus;
            int m_keskusmuisti;
        public:
            KeskusYksikko();
            KeskusYksikko();
            void SetTunnus(int tunnus);
            int GetTunnus();
            void SetProfessori(int presessori, int kellotaajuus);
            void GetProsesori(int& prosessori, int  kellotaajuus);
            void SetMuisti(int muisti);
            int GetMuisti();
    }

6.1.2 Aggregaatit koodina

    class naytto;
    class keskusyksikko;
    class ohjaulaitelista;

    class tietokone {
        private:
            int m_number;
            int naytto *m_naytto;
            int m_numero;
            keskusyksikko *m_keskusykksikko;
            ohjauslaitelista * m_ohjauslaitteet;
        public:
            Tietokone();
            Tietokone();
            int GetNumero();
            void SetNumero(int numero);
    }

6.1.3 Periytyminen koodina

    class Location {
        . . .
    }

    class Point : public Location { // Periytyy paikka -luokasta,
        . . .                       // Ts. kayttaa location:in
    }                               // attribuutteja (mikali ei ylimaaritelty).

6.1.4 Assosiaatioiden toteutus

Assosiaatioden yhteydessä usein mietityttää, miten oliot saavat tiedon toisistaan. Miten hevonen saa tietää, kuka sen omistaa tai mistä omistaja tietää, mitä hevosia hän omistaa? Assosisaatioiden toteutuksessa voi joko valita yhtenäisen tavan toteuttaa kaikki assosiaatiot tai valita tavan, joka riippuu assosiaation käyttötarkoituksesta. Esimerkiksi tarvitseeko hevosen tietää sen omistaja vai riittääkö, että omistaja tietää mitä omistamansa hevoset? Abstraktisti ajateltuna assosiaatiot ovat aina kahdensuuntaisia, mutta assosiaatioiden käyttötapa voi kuitenkin joissakin tapauksissa olla vain toiseen suuntaan.

Jos assosiaatiot kulkevat vain toiseen suuntaan, voidaan ne toteuttaa yksinkertaisemmin. Valitettavasti usein käy kuitenkin niin, että toiveet muuttuvat matkan varrella ja toiseenkin suuntaan haluttaisiin kulkea (varsinkin kun siihen on opittu relaatiomallissa). Jos assosiaatiot toteutetaan vain toiseen suuntaan, voidaan se toteuttaa osoittimien avulla. Osoittimen avulla voidaan navigoida toiseen osapuoleen, esim. omistajaan liitetään osoitin hevoseen. Jos yhteys on yhden-suhde-yhteen, tämä riittää. Jos yhteys on yhden-suhde-moneen tarvitaan osoitinlista, jota pitkin päästään navigoimaan kaikkiin omistajan hevosiin.

Jos yhteyttä kuljetaan molempiin suuntiin, on olemassa kolme vaihtoehtoa toteuttaa asia:
- Toiseen suuntaan pointerilla, jolloin suoritetaan haku kuljettaessa yhteyttä toiseen suuntaan.
- Molempiin suuntiin pointereilla. Jos nyt toisessa suunnassa pointerin arvo muuttuu, täytyy muutos päivittää myös toiseen suuntaan.
- Toteutetaan assosiaatio omana luokkanaan, jossa on pointerit molempiin suuntiin. Tähän ratkaisuun on mahdollista lisätä myös hakuavaimen perusteella tapahtuva etsintä. Tämä tapa on hyvä myös silloin, kun kaikki oliot eivät osallistu assosiaatioon (eli joku omistaja ei omista hevosta ollenkaan). Tällöin ei varata turhaan tilaa pointereille.

Useissa olio-ohjelmointikielissä on määritelty luokka, jonka avulla voidaan tallentaa luokan esiintymiä ja hakea niitä. Tämä luokka luodaan kaikille niille luokille, joiden instansseja halutaan tallentaa kokoelmina (Visual C++:n Collection-luokat). Kokoelma on periaatteessa taulukko tai lista. Se voidaan laajemmassa mittakaavassa ymmärtää jopa relaatiotietokannan taulukkona tai osana sitä. Kokoelman käsittelyyn on seuraavia operaatioita: kokoelmaluokan luonti, esiintymän lisäys kokoelmaan, sen poisto ja etsiminen, esiintymän lukumäärä kokoelmassa, kokoelman iterointi yksi kerrallaan jne. Operaatioiden nimet ja toteutustavat vaihtelevat välineittäin.

Jos halutaan käsitellä sovelluksessa esim. useita omistajaluokan olioita kerralla (esim. laskutus), täytyy luoda kokoelmaluokka omistajaa varten. Jos halutaan käsitellä omistajan hevosia, täytyy lisätä omistajaan hevoskokoelmaluokka ja operaatiot sen käsittelyyn, esim. GetHevoset(). Hevoseen voidaan taasen lisätä operaatio, jonka avulla löytyy hevosen omistaja (esim. pointteri omistajaan).

Linkkiluokka voidaan toteuttaa esimerkiksi siten, että se puretaan kolmeksi erilliseksi luokaksi, joiden välillä vallitsee relaatiomallista tuttu yhteys. Assosiaatiot toteutetaan kuten edellä.

6.2 Olioiden tallentaminen

Oliomallin oliot voivat olla säilyviä tai häviäviä. Olio katsotaan säilyväksi, jos se arvosisältöineen on käytettävissä vielä sovelluksen sulkeuduttua. MVC-mallin Model-osan oliot ovat säilyviä osia. Säilyvät oliot vastaavat oliopohjaisen sovelluksen tietokantaa.

Säilyvällä oliolla on usein vastine reaalimaailmassa (esim. asiakas, hevonen ja tilaus). Häviäviä olioita ovat esim. listan käsittelyä, raportointia ja ikkunointia varten luodut oliot. Varmaa tapaa tunnistaa säilyvät ja häviävät oliot ei ole, vaan samanniminen olio voi yhdessä mallissa olla säilyvä ja jossain toisessa häviävä. Säilyvä olio voi olla joko tiedosto tai relaatiotietokannan taulu.

Lähdettäessä suunnittelemaan oliomalliin perustuvaa sovellusta ideaalitavoitteena on tilanne, jossa oliomallia ei rasiteta tarpeettomilla tiedonhallintaan liittyvillä metodeilla. Ratkaisun täytyy kuitenkin tarjota riittävän hyvä pohja toteutukselle.

Seuraavassa esitellään säilyvien olioiden talletusvaihtoehtoja.

6.2.1 Tiedostot

Jokaiselle luokalle tehdään Load()- ja Save()-metodit. Yksinkertaisen tiedostoon tallennusvaihtoehdon pohjalta on luotu useita valmiita kirjastoratkaisuja (esim. Visual C++:n Serialize-makrot). Perusperiaatteena näissä on luokka, johon on toteutettu talletus- ja lukuoperaatiot. Muut luokat periytyvät tästä yliluokasta ja saavat siten käyttöönsä tiedosto-operaatiot.

Tiedostoratkaisuun päädytään, kun sovelluksessa ei tarvita monimutkaisia kyselyitä, samanaikaista käyttöä jne., vaan pärjätään perusoperaatioilla. Tiedostoratkaisuun on käytössä sopiva kirjasto, joten se on nopea ja halpa ratkaisu. Oman kirjaston tekeminen olisi aikaa vievää ja kallista hommaa.

6.2.2 Relaatiotietokannat

Relaatiotietokanta on tämän hetken markkinajohtaja. Vuonna 1993 74% myydyistä tietokantatuotteista oli relaatiotietokantoja. Kaupallisia tuotteita on useita (esim. Oracle ja Ingres). Relaatiotietokantoja käytetään SQL-kielen avulla, joka on standardoitu kyselykieli (myös päivitykset).

Relaatiotietokantoja käyttävät sovellukset ja itse tietokantamoottori ovat asiakas-palvelin-arkkitehtuuria puhtaimmillaan. Relaatiotietokannoissa on mahdollistettu tietojen hajauttaminen fyysisesti eri palvelimiin. Relaatiotietokannat ovat tällä hetkellä kypsiä, luotettavia ja kohtuullisen tehokkaita tiedonhallintavälineitä.

Relaatiotietokanta koostuu tauluista, jotka koostuvat riveistä ja sarakkeista. Rivit ovat itse asiassa tietueita ja sarakkeet kenttiä. Taulun rivien ja sarakkeiden järjestyksellä ei ole merkitystä. Sarakkeen alkiot ovat kaikki samaa tyyppiä ja niillä on loogisesti sama merkitys kautta taulun. Taulujen käsittely tapahtuu relaatioalgebran operaatioilla, joita ovat esim. valinta ja liitos. Suoritustehoa parannetaan indeksien avulla. Taphtumien eheyden takaa tietokannan hallintajärjestelmä.

Markkinoilla olevat tuotteet tarjoavat mm. seuraavia rajapintoja tietokannan ja sovelluksen välille: Embedded SQL, ODBC, IDAPI. Näistä ylivoimaisesti suosituin on viimeaikoina ollut ODBC eli Open DataBase Connectivity, joka on Microsoftin Windowsin ja NT:n käyttämä tietokanta-ajuri. Se mahdollistaa tuoteriippumattoman kehityksen ja siinä on käytössä n. 40 funktiota.

Relaatiotietokantaratkaisuun päädytään, kun dataan kohdistuu satunnaisia kyselyitä (raportointi), kun asiakas-palvelinarkkitehtuuri sopii sovelluksen ideologiaan parhaiten, kun hallittavaa dataa on paljon, kun sovellus halutaan kehittää sovelluskehittimillä, kun tietoturva ja toipumismenettelyt ovat tärkeitä, tai kun tietoja halutaan monimutkaisten tietojen takaa ja uusia yhteyksiä taulujen välillä syntyy kuin sieniä sateella. Edellisiä kohtia pohdittaessa täytyy myös muistaa, että relaatiotietokantakulttuuri on yrityksissä vahvoilla.

6.2.3 Oliotietokannat

Oliotietokantojen tarpeen on synnyttänyt olioajattelun yleistyminen ohjelmistotuotannossa. Tavoitteena oliotietokantojen käytössä voidaan pitää jo muista yhteyksistä tutuksi tullutta tuottavuuden parantamista. Kun oliomallin ja tietokannan rakenteen välillä ei vallitse ristiriitaa, on olioiden tallentaminen ja niiden käsittely huomattavasti jouhevampaa. Oliotietokantojen yleistymistä odotellaan vielä, sillä esim. vuonna 1994 26:sta tietokanta-asennuksesta vain yksi oli oliotietokanta.

Oliotietokantaa tulee harkita, kun sovelluksen suorityskyky on erityisen tärkeä, kun sovelluksen toteutus perustuu oliomalliin, kun sovelluksen luonne on vaaraton (lentokoneet eivät tipu maahan, jos jokin menee pieleen), tai kun sovelluksella ei ole yhteyttä mihinkään olemassa olevaan relaatiotietokantaan. Ennen edellisten pohtimista tulee selvittää, löytyykö kyseessä olevalle laite/käyttöjärjestelmä/kääntäjä-kombinaatiolle oliotietokantatoteutusta (suurin osa Unixille ja PC:lle) eli onko siirtyminen oliotietokantaan edes mahdollinen. LINT95, AALT94.


7. Select OMT 5.0

Select OMT Professional on Rumbaughin OMT:hen ja Jakobsonin OOSE:en perustuva suunnitteluohjelmistotuote. Ohjelmisto on saanut varsin korkean suosion oliokehittäjien keskuudessa eritoten sen edullisen hinnan takia.

Suunnittelu aloitetaan yleensä laatimalla käyttötilannemalli (Use Case), jossa hahmotellaan ja kartoitetaan ongelmaa hyvin yksinkertaisella tasolla. Mallia kehitellään kunnes kaikki ovat tyytyväisiä siihen (suunnittelijat,asiakkaat jne.). Tämän jälkeen kaikilla on yleiskuva ongelmasta. Käyttötilannemalli (kuva 15) ei varsinaisesti kuulu OMT-menetelmään, vaan se on lisätty tuotteeseen helpottamaan suunnittelun alkuvaiheita.

Kuva 16. Pankkiautomaatin käyttötilannemalli.

Tämän jälkeen edetään normaalisti alkaen määrittelyvaiheesta, jossa suunnitellaan oliomalli (kts. kuva 1). Oliomallin jokaiselle oliolle voidaan luoda dynaamisen mallin mukaiset skenaariot (kts. kuva 2) ja tilasiirtymäkaaviot (kts. kuva 3). Edelliset mallit on yhdistetty toisiinsa linkeillä, joita pitkin voi siirtyä mallista toiseen. Erityisesti oliomallissa on runsaasti tilaa sanallisille kuvauksille (description), jossa jokaiseen olioluokkaan, sen attribuuttiin ja sen metodiin voidaan liittää tarkentava sanallinen kuvaus.

Kolmas eli toiminnallinen malli voidaan laatia yleinen grafiikka (general graphics) -diagrammina (kts. kuva 4). Varsinaiset linkit muihin malleihin puuttuvat ainakin ohjelmiston tästä versiosta.

Select OMT 5.0:n lisämoduleina voi hankkia dokumenttigeraattorin, jolla luodaan pohja projektista luotavalle raportille. Raportin pohja generoidaan OMT-diagrammeista, jonka jälkeen projektipäällikkö tms. kommentoi projektin hallintaan liittyvät asiat.

Muina lisätuotteina voidaan mainita C++ Generator, joka luo otsikkotiedostot (*.h) oliomallin olioiden, attribuuttien, metodien ja niiden tarkennusten pohjalta. Tämä vaihe korvaa ainakin osan kappaleessa 6 käsitellystä toteutusvaiheesta.

C++ Reverse Engineering -moduli luo pohjan OMT-dokumentoimattoman koodin jälkikäteen tapahtuvan OMT-dokumentoinnille KIUR96.


8. UML

Ensimmäiset tunnistettavat oliopohjaiset metodit ilmestyivät 80-luvun loppupuolella. Vuosien kuluessa syntyi suuri määrä eri lähestymistavan omaavia kokeiluja oliopohjaiseen määrittelyyn ja suunnitteluun. Näiden kokeilujen ja alan kypsymisen myötä yhä usemmat alan tutkimusprojektit alkoivat omaksua tuotteen laadun ja tehtävä kriittisten systeemien idean. 90-luvun puolessavälissä alkoikin ilmestyä muutamia toisen sukupolven metodeita, joista merkittävimpiä Booch'94, OMT:n jatkunut kehitys ja Fusion.

Booch- ja OMT-metodit alkoivat itsenäisesti kasvaa yhteen ja olivat hallitsevia maailmanlaajuisia oliopohjaisia suunnittelumetodeita. Lokakuussa 1994 Booch ja Rumbaugh yhdistivät voimansa luodakseen yhdistelmän omista töistään. Molemmat olivat alkaneet metodeissaan omaksua Ivar Jakobsenin käyttötilanteita (Use Case, vrt. Select OMT 5.0, kuva 6), ja näin ollen myös hän liittyi vuotta myöhemmin tähän yhteenliittymään.

Tämän yhteenliittymään nimeksi on vakiintumassa The Unified Modeling Language (yhdistetty mallinuskieli) eli UML. Sitä ollaan parhaillaan kehittelemässä lopulliseen muotoonsa yhdessä asiasta kiinnustuneiden tulevien sovelluksen käyttäjien ja yhteenliittymän, Rational Software Corporationin, kanssa. Kehitystyö tapahtuu internetin välityksellä siten, että Rational julkaisee aika ajoin versioita tästä standardista. Siinä on mainittu muutokset ja korjaukset edelliseen versioon verrattuna, mitä vielä on tekemättä sekä alustavat esitykset, joihin erityisesti toivotaan käyttäjien kommentteja. Viimeisin versio 0.91 julkaistiin 27.9.1996, jolloin arvioitiin, että standardi hyväksyttäneen loppuvuodesta 1996 tai alkuvuodesta 1997 RATI96.

UML on oliopohjaisen systeemin kehittelyn aikaiseen erittelyyn, visualisointiin ja ihmiskäden aikaansaamien tuotosten dokumentointiin tarkoitettu kolmannen sukupolven mallinnuskieli. Erityisen tarkoituksenmukainen (edeltäjiinsä verrattuna) se on suunniteltaessa reaaliaikaisia systeemejä. Edeltäjiinsä verrattuna UML on yksinkertaisempi, johdonmukaisempi ja ilmaisevampi. Kuitenkin se on Booch:n, OMT:n ja muiden vastaavien luonnollinen seuraaja ja näinollen myös yhteensopiva näiden kanssa.

UML tarjoaa tuen luokille ja olioille sekä monenlaisille niiden välisille assosiaatioille, kuten aggregaatti, uses, riippuvaisuus, perintä ja esiintyminen. Käyttötilanteet (Use Case) ovat yhteydessä skenaario-mallinnukseen tarjoten tarvittavan systeemin käytöksen yksityiskohtaisen kuvauksen. Nämä käytösmallit voivat sisältää sekä ajoitukseen että prosessien synkronointiin liittyvää tietoa.

Edellä kuvatut ominaisuudet ovat vain esimerkkejä UML:n ominaisuuksista, eikä niiden yksityiskohtainen tarkastelu standardoinnin tässä vaiheessa ole olennaista RATI96. UML:stä, tai mikä sen nimeksi tulevaisuudessa sitten tuleekaan, tulee varsin todennäköisesti vuositunhannen vaihteessa aikaisemmat oliopohjaiset määrittely ja suunnittelumenetelmät syrjäyttävä kieli, jonka tulisi siirtää ohjelmistotuotannon painopistettä varsinaisen koodauksen puolelta yhä enemmän suunnitteluun.


Lähteet

RUMB96 : Rational Software Corporation, Dr. James Rumbaugh ("kotisivu") , 1996.

BAKK96 : Bakker Gerbrand , OMT Object Model , 1996.

LINT95 : R. Linturi Oy , OMT -suunnittelumenetelmä , 1995.

AALT94 : Aalto Juha-Markus , Oliokeskeinen määrittely ja suunnittelu , Nokia Cellular Systems , Network Management Systems , 1994.

KIUR96 : Kiuru Risto , Select OMT -kurssimateriaali , H&P Software Engineering Center Oy , 1996.

RATI96 : Rational Software Corporation , The Unified Modeling Language , http://www.rational.com/ot/uml.html, 1996.