anttipuhakka_bitwise_web

Tilakonetta voi käyttää reaktiivisen ohjelmistojärjestelmän mallintamiseen ja toteutukseen tilanteessa, jossa täytyy sekä reagoida reaalimaailmasta tuleviin tapahtumiin että saada vastineeksi aikaan muutoksia maailmassa. Esimerkkinä käytän valvontajärjestelmää suljetulle tilalle.

Tilakoneella tarkoitetaan systeemiä, joka koostuu tiloista ja niiden välisistä tilasiirtymistä. Tilasiirtymiä aiheuttavat yleensä jotkin ulkoa tulevat syötteet, ja ne voivat tuottaa ulospäin näkyviä tuloksia.

Yksinkertaisimmillaan tilakone lukee jonoa symboleita, suorittaa tilasiirtymiä syötteiden mukaisesti ja joko hyväksyy tai hylkää tietyt syötejonot tai tuottaa siirtymien tuloksena jonon tulosarvoja. Tämä äärelliseksi automaatiksi kutsuttu malli on lähellä säännöllisten lausekkeiden käsitettä ja on keskeinen malli tiedon jäsentämisessä ja kääntäjätekniikassa. Toinen yleinen käyttö tilakoneille on erilaisten kommunikaatioprotokollien suunnittelussa ja standardoinnissa, jossa tilakone kertoo millainen on kommunikoivien osapuolten oikea toiminta.

Tilakone ja reaktiiviset järjestelmät

Seuraavassa käytämme esimerkkinä valvontajärjestelmää suljetulle tilalle. Kuviteltu järjestelmä sisältää ainakin koodilla lukitun oven ja liikesensorin. Haluamme, että tunkeutuminen huoneeseen ilman koodia aiheuttaa hälytyksen. Oikean pin-koodin syöttäminen taas avaa oven ja estää hälytyksen. Valvontajärjestelmä voidaan myös kytkeä päälle tai pois etävalvomosta käsin.

Tämän kaltaista järjestelmää toteutettaessa huomataan usein, että koodiin alkaa kertyä ehtoja, joissa testataan erilaisten tilalippujen arvoja. Esimerkkijärjestelmän toteutuksen koodissa saattaisi näkyä ehtoja, kuten if (!off), kun tietty asia halutaan tehdään vain, kun järjestelmä on kytketty päälle, tai vaikka if (alarm && !alarm_sent), kun haluamme lähettää hälytyksen valvomoon, mutta vain kerran. Pienessä järjestelmässä tällaiset ehdot on vielä helppo hahmottaa. Kun toiminnallisuutta tulee lisää, voi samantapaisia ehtoja alkaa esiintyä monessa paikassa, ehdot muodostuvat monimutkaisiksi ja riski kasvaa, että ehtojen testaaminen unohtuu jonkin operaation toteutuksessa tai ehdot voivat olla väärin.

Tilat ja tilasiirtymät

Edellä kuvatun kaltaisten ehtojen esiintyminen on vinkki siitä, että järjestelmän kaikesta tilasta voidaan erottaa kokonaisuuksia, joista kussakin järjestelmä reagoi syötteisiin juuri sille ominaisella tavalla. Esimerkkijärjestelmässä voidaan erottaa esimerkiksi poiskytketty eli “Off”-tila, jossa ei tehdä muuta kuin odotetaan järjestelmän käynnistämistä. Sitten voimme erottaa tilan, jossa järjestelmä on päällä, mutta mitään ei ole vielä tapahtunut, eli ”Idle”-tilan, jossa odotetaan pin-koodin syöttämistä lukkoon tai järjestelmän poiskytkentää, ja niin edelleen. Tällaisia ylätason tiloja kutsutaan kvalitatiivisiksi tiloiksi. Tilakoneeseen perustuvan lähestymistavan ideana on, että nämä kvalitatiiviset tilat nostetaan suunnittelun lähtökohdaksi, sen sijaan että niihin liittyvä logiikka olisi hajallaan siellä täällä koodin seassa.

Kvalitatiivisten “perustilojen” lisäksi järjestelmässä voi olla muuttujia, jotka kuvaavat jotakin arvoa, mutta siten että arvon muutos ei välttämättä muuta järjestelmän käyttäytymisen luonnetta. Tällaisia tilamuuttujia kutsutaan kvantitatiivisiksi. Esimerkkijärjestelmässämme voisi olla muuttuja, joka seuraa huoneen lämpötilaa. Meitä ei sinänsä kiinnosta suuresti, jos lämpötila nousee vaikka 18.3°:sta 20.1°:een. Toisaalta jos lämpötila ylittää jonkin kriittisen rajan, aiheuttaa tämä hälytyksen, ja järjestelmä siirtyy tällöin uuteen kvalitatiiviseen tilaan. Toinen vastaava esimerkki voisi olla muuttuja, joka pitää kirjaa väärien yritysten määrälle avauskoodin syötössä.

Eräs hyvä puoli tilakoneissa on mahdollisuus esittää ne graafisena kuvana. Alla olevassa kuvassa on esitetty yksinkertainen malli esimerkkinä olevalle valvontajärjestelmälle:

Tilakoneen siirtymiin on merkitty, mikä syöte laukaisee ne. Tilakoneen tilasiirtymät voivat lisäksi olla ehdollisia kvantitatiivisten tilamuuttujien suhteen. Kuvassa ehto on merkitty siirtymän viereen hakasulkeisiin. Tilasiirtymiin voidaan toisaalta liittää toimenpiteitä, joilla ohjataan ulkopuolista maailmaa, esimerkkinä lukon avaus tai hälytyksen lähettäminen. Kuvassa siirtymän aiheuttama toimenpide on kirjoitettu kauttaviivan jälkeen.

Tilakoneet ovat hyvä väline suunnitteluun ja keskusteluun oikeasta toiminnasta. Voimme tarvittaessa keskittyä yhteen tilaan kerrallaan ja pohtia, millä tavalla juuri siinä tilassa pitää reagoida. Visuaalinen esitystapa helpottaa järjestelmän hahmottamista ja voi tuoda uusia näkökulmia. Analysoitaessa järjestelmän toimintaa jälkikäteen esimerkiksi lokien perusteella, atomiset siirtymät tilasta toiseen tarjoavat selkeitä jakokohtia tapahtumien vyöryssä.

Tilakoneista on olemassa laaja UML-standardi, joka sisältää äärellisen automaatin mallin lisäksi monia kehittyneempiä toiminnallisuuksia, kuten vahdit, hierarkiset tilakoneet ja rinnakkaiset tilat,  historiatilat ja viivästetyt tapahtumat [UML].

Tilakoneen toteuttaminen

Entä miten tilakoneena kuvattua mallia järjestelmästä pitäisi lähteä toteuttamaan jossakin oikeassa kehitysympäristössä? Artikkeleita ja kirjoja on kirjoitettu siitä, miten esimerkiksi UML-standardin mukainen tilakone pitäisi toteuttaa. Osa näistä kuvaa yleisemmällä tasolla, millaisia tapoja on kuvata tilakonemallin piirteitä olio-ohjelmoinnin käsitteiksi, lähtien yleensä kehittämään eteenpäin ns. State-patternia [Gamma et al], [Dyson et al],[Yacoub et al]. Osa käsittelee näiden mallien toteuttamista tietyn ohjelmointikielen kautta tai jopa hyvinkin yksityiskohtaisesti sitä, miten tietyn ohjelmointikielen piirteitä voidaan käyttää tehokkaaseen toteutukseen [Niaz et al], [Samek]. On myös olemassa työkaluja, joiden avulla voi määritellä tilakoneita graafisessa ja/tai tekstuaalisessa muodossa ja muuntaa tulos ohjelmakoodiksi, esimerkkeinä [Qfsm], [SMC], [Ragel] ja [YAKINDU].

Näitä lähteitä lukemalla ei kuitenkaan välttämättä löydä yleispätevää vastausta moniin käytännön kysymyksiin, joihin törmää, kun tilakonetta lähtee oikeasti toteuttamaan. Miten säikeet ja lukitus hoidetaan? Kuka siirtää tilakonetta? Miten taataan tilasiirtymien atomisuus ja mitä se tarkkaan ottaen pitää sisällään? Mitä voidaan taata ulostulevien tapahtumien aikajärjestyksestä suhteessa toisiinsa? Entä suhteessa syötetapahtumiin?

Kirjoitussarjan seuraavissa osissa esittelen kaksi erilaista mallia siihen, miten tilakoneen voi toteuttaa Javan tai C#:n kaltaisella olio-ohjelmointikielellä. Ensimmäinen näistä on lähellä edellä mainituissa lähteissäkin kuvattuja malleja, toinen taas tulee lähestymään asiaa hieman uudenlaisesta näkökulmasta. Mallien esittelyn jälkeen kuvaan erilaisia haasteita, joita tilakoneen toteutuksessa esiintyy ja sitä, miten nämä mallit pystyvät haasteisiin vastaamaan.



Viitteet:
[UML]
OMG Unified Modeling Language (OMG UML), Superstructure, Version 2.2. Luku 15: State Machines. http://doc.omg.org/formal/2009-02-02.pdf. Katso myös Wikipedia-artikkeli: https://en.wikipedia.org/wiki/UML_state_machine
[Gamma et al]
Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. ”Design patterns: elements of reusable object-oriented software”. Addison-Wesley 1995.
[Dyson et al]
Paul Dyson, Bruce Anderson. ”State patterns.” Pattern languages of program design 3 (1996): ss. 125-142.
[Yacoub et al]
Sherif Yacoub, Hany Ammar. ”A pattern language of statecharts.” Proc. Fifth Annual Conference on the Pattern Languages of Programs (PLoP’98). 1998.
[Niaz et al]
I. Niaz, J. Tanaka: ”Mapping UML statecharts to java code.” IASTED Conference on Software Engineering, 2004.
[Samek]
Miro Samek: Practical Statecharts in C/C++. CMP Books 2002.
[Qfsm]
Qfsm: A graphical tool for designing finite state machines, http://qfsm.sourceforge.net/download.html
[SMC]
SMC: The State Machine Compiler,http://smc.sourceforge.net/
[Ragel]
Ragel State Machine Compiler, http://www.colm.net/open-source/ragel/
[YAKINDU]
YAKINDU Statechart Tools, https://www.itemis.com/en/yakindu/statechart-tools/