VAASAN YLIOPISTO TEKNIIKAN JA INNOVAATIOJOHTAMISEN YKSIKKÖ OHJELMISTOTEKNIIKKA Janne Vierula PORTIT JA ADAPTERIT -ARKKITEHTUURIN SOVELTAMINEN KETTE- RÄSSÄ OHJELMISTOKEHITYKSESSÄ Diplomityö. joka on jätetty tarkastettavaksi diplomi-insinöörin tutkintoa varten Vaasas- sa 9.4.2019. Työn valvoja Professori Jouni Lampinen Työn ohjaaja DI Arvi Lehesvuo 1 SISÄLLYSLUETTELO sivu 1 JOHDANTO 4 2 TAAJUUSMUUTTAJAT 6 2.1 Toiminnallinen turvallisuus 6 3 KETTERÄT MENETELMÄT 10 3.1 Säännölliset tilannepalaverit käytäntö 10 3.2 Iteraatio käytäntö 10 4 OHJELMISTOARKKITEHTUURIT 12 4.1 Kerrosarkkitehtuuri 12 4.2 Suunnittelumallit ja periaatteet 13 4.3 Portit ja adapterit -arkkitehtuuri 19 5 TUTKIMUSMENTELMÄ JA LÄHTÖTILANNE 23 5.1 Keskeneräiset portit ja sovittimet ennen työn aloitusta 30 6 TYÖN OSUUS 34 6.1 Parametritiedoston rakenne 34 6.2 Toimintojen käsittelijät 41 6.3 Demo datan generointi 50 6.4 JSON-rajapinnan validointi 53 6.5 Kommunikaatiokirjaston integraatio 57 6.6 Tulokset 58 7 JOHTOPÄÄTÖKSET 64 2 VAASAN YLIOPISTO Tekniikan ja innovaatiojohtamisen yksikkö Tekijä: Janne Vierula Diplomityön nimi: Portit ja adapterit -arkkitehtuurin sovelta- minen ketterässä ohjelmistokehityksessä Valvojan nimi: Professori Jouni Lampinen Ohjaajan nimi: DI Arvi Lehesvuo Tutkinto: Diplomi-insinööri (DI) Ohjelma: Tietotekniikan koulutusohjelma Suunta: Ohjelmistotekniikka Opintojen aloitusvuosi: 2012 Opintojen valmistumisvuosi: 2019 Sivumäärä: 69 TIIVISTELMÄ: Ketterien menetelmien käyttö ohjelmistokehityksessä on nykypäivän trendi. Portit ja adapterit -arkkitehtuuria suositellaan käytettäväksi ketterässä ohjelmistokehityksessä, koska sen käyttö parantaa ohjelmiston ylläpidettävyyttä, joka on tärkeää ketterässä oh- jelmistokehityksessä. Tutkimuksessa pyritään todentamaan portit ja adapterit - arkkitehtuurin soveltuvuutta ketterään ohjelmistokehitykseen. Tutkimus suoritettiin tapaustutkimuksena analysoimalla PC-työkalu projektin Business- logiikan toteutusta Scrum-käyttäjätarinoiden kautta. Projektin tavoitteena oli saada toi- mitettua kohdeyritykselle asiakasvaatimukset täyttävä PC-työkalu taajuusmuuttajan toiminnallisen turvallisuuden konfigurointiin. Projektissa käytettiin ketterien ohjelmis- tokehitysmenetelmien käytäntöjä ja PC-työkalun Business-logiikan arkkitehtuurina käy- tettiin portit ja adapterit -arkkitehtuuria. Business-logiikan tarjoaman rajapinnan for- maattina käyttöliittymälle käytettiin JavaScript Object Notation -formaattia. Business- logiikka toteutettiin C#-ohjelmointikielellä. Projektin tulokseksi saatiin asiakasvaatimukset täyttävä PC-työkalu taajuusmuuttajan toiminnallisen turvallisuuden konfigurointiin. Tutkimuksen aikana todettiin, että portit ja adapterit -arkkitehtuurin soveltuu käytettäväksi ketterässä ohjelmistokehityksessä. Portit ja adapterit -arkkitehtuurin soveltuvuus ketterään ohjelmistokehitykseen johtuu osittain siitä, että portit ja adapterit -arkkitehtuurista löytyy yhtenäisyyksiä suosittuihin ketterässä ohjelmistokehityksessä käytettyihin suunnitteluperiaatteisiin vakaat riippu- vuudet ja riippuvuusinversio. Vakaat riippuvuudet ja riippuvuusinversio - suunnitteluperiaatteiden käyttö parantaa muunneltavuutta, joka on ylläpidettävyyden komponentti. AVAINSANAT: Toiminnallinen turvallisuus, ketterät menetelmät, Ylläpidettävyys, Portit ja Adapterit -arkkitehtuuri 3 UNIVERSITY OF VAASA The School of Technology and Innovations Author: Janne Vierula Topic of Thesis: Applying the ports and adapters -architecture to agile software development Supervisor: Professor Jouni Lampinen Instructor: M.Sc. (Tech.) Arvi Lehesvuo Degree: Master of Science in Technology Degree Programme: Degree Programme in Information Technology Option: Software Engineering Year of Entering the University: 2012 Year of Completing the Thesis: 2019 Pages: 69 ABSTRACT: Agile software development is a trend nowadays. Usage of Ports and Adapters - architecture is recommended because ports and adapters architecture improves main- tainability of the software. This study attempts to verify suitability of ports and adapters -architecture in agile software development. Study was conducted as a case-study by analyzing implementation of business logic of a PC-tool trough scrum user stories. Target of the project was to deliver a PC-tool for customer which could be used to configure the functional safety of a frequency convert- er. Agile software development practices were utilized in the project and ports and adapters architecture was selected as architecture for the business logic of the PC-tool. JavaScript Object Notation -format was used in the Interface between the user interface and the business logic. Business logic was implemented using C#-programming lan- guage. Result of the project was customer requirement fulfilling PC-tool which can be used to configure the functional safety of a frequency converter. During the study it was found out that ports and adapters -architecture is suitable to be used in agile software devel- opment. Study showed that Suitability of ports and adapters -architecture to agile soft- ware development can partly be explained because ports and adapters architecture has similarities to popular agile design principles called Stable Dependencies and Depend- ency Inversion. Usage of Stable Dependencies and Dependency Inversion design prin- ciples increases changeability which is a component of maintainability. KEYWORDS: Functional safety, Agile software development, Maintainability, Ports and adapters -architecture 4 1 JOHDANTO Perinteinen tapa kontrolloida laitteiden, kuten pumppujen ja tuulettimien nopeuksia sähkömoottorin avulla on käyttää vaihteistoa. Vaihteiston käyttö nopeuden kontrol- loimiseen on kuitenkin epätarkkaa. Viime aikoina taajuusmuuttajat ovat korvanneet perinteiset tavat kontrolloida laitteiden pyörimisnopeuksia teollisuudessa, koska taa- juusmuuttajat ovat energiatehokkaampia, huoltovapaampia ja taajuusmuuttajiin integ- roitu toiminnallinen turvallisuus vähentää järjestelmän monimutkaisuutta. Toiminnalli- nen turvallisuus on tärkeää esimerkiksi elintarviketuotannossa, jossa sen tehtävänä var- mistaa, että pyörivä laite pysäytetään hallitusti vaaratilanteen sattuessa, esimerkiksi varmistaa, että sokerin tuotannossa käytettävä linko pysäytetään hallitusti siinä tapauk- sessa, että laitteen käyttäjä tarttuu pyörivään linkoon. (ABB 2016a.) Ketterä ohjelmistokehitys on nykypäivän trendi, jolla pyritään vähentämään perinteisten ohjelmistokehitysmenetelmien ongelmia suoriutua muuttuvista vaatimuksista. Robertin (Martin 2003: 85) mukaan ketterä ohjelmistokehitys vaatii, että koodi on helposti yllä- pidettävää. Ylläpidettävyys koostuu IEC 25023 (ISO/IEC 25023 2016: 25–27) mukaan analysoitavuudesta, testattavuudesta, modulaarisuudesta, muunneltavuudesta ja uudel- leenkäytettävyydestä. Alistairin mukaan (Cockburn 2007: 275) portit ja adapterit - arkkitehtuuria suositellaan käytettäväksi ketterissä ohjelmistoprojekteissa, koska se pa- rantaa ohjelmiston testattavuutta. Mahdollisuus tutkia portit ja adapterit -arkkitehtuurin soveltuvuutta ketterään ohjelmistokehitykseen käytännön työelämässä herätti mielen- kiinnon paneutua portit ja adapterit -arkkitehtuurin ja ylläpidettävyyden suhteeseen. Työssä pyritään todentamaan portit ja adapterit -arkkitehtuuri soveltuvuutta ketterään ohjelmistokehitykseen tapaustutkimuksen kautta. Tapaustutkimuksen materiaalina käytettiin projektia, jonka aiheena oli taajuusmuuttajan kanssa kommunikoivan PC-työkalun toteutus Windows ympäristöön. PC-työkalun käyt- tötarkoitus oli taajuusmuuttajan toiminnallisen turvallisuuden konfigurointi. Toiminnal- lisen turvallisuuden konfiguroinnilla tarkoitetaan IEC 61800-5-2 määritettyjen turva- 5 funktioiden parametrien muokkaamista ja turvafunktioiden parametrien arvojen siirtä- mistä taajuusmuuttajalle. Toteutettu PC-työkalu voidaan jakaa kolmeen osaan, jotka ovat Käyttöliittymä, Business-logiikka ja Kommunikaatiokirjasto. Projektissa käytettiin ketteriä ohjelmistokehitys menetelmiä ja PC-työkalun arkkitehtuurina käytettiin portit ja adapterit -arkkitehtuuria. Tapaustutkimuksen materiaalina käytettiin projektissa C#- ohjelmointikielellä toteutettua PC-työkalun business-logiikkaa. Kappaleessa 2 käsitellään taajuusmuuttajiin liittyvää toiminnallista turvallisuutta. Kap- paleessa 3 käsitellään ketteriä menetelmiä ohjelmistokehityksessä. Kappaleessa 4 käsi- tellään työn kannalta keskeisimpiä suunnittelumalleja, suunnitteluperiaatteita ja arkki- tehtuureja. kappaleessa 5 käydään läpi projektin lähtötilanne ja tutkimusmenetelmä. Kappaleissa 6 käydään läpi PC-työkalun käyttäjätarinoiden toteutuksia ja analysoidaan käyttäjätarinoiden tuloksiksi saatujen komponenttien ylläpidettävyyttä. Kappaleessa 7 analysoidaan tutkimuksen tulosten paikkaansa pitävyyttä vertaamalla tuloksia teoriaan, sekä käydään läpi mahdollisia jatkotutkimus ideoita. 6 2 TAAJUUSMUUTTAJAT Perinteinen tapa kontrolloida esimerkiksi ilmanvaihtokonetta sähkömoottoria käyttäen on pyörittää moottoria vakionopeudella ja säätää ilman virtausnopeutta mekaanisella kuristimella. Perinteinen tapa ei ole energiatehokas, koska täyttä ilmavirtausnopeutta tarvitaan vain 1–5 % käyttöajasta. Taajuusmuuttajan avulla sähkömoottoria pyöritetään aina vaaditulla nopeudella, jolloin energiakustannukset pienenevät ja moottorin elinikä kasvaa. (Piper 2009.) 2.1 Toiminnallinen turvallisuus Toiminnallisen turvallisuuden tehtävä on tunnistaa vaaratilanne ja estää vaaratilanteesta aiheutuva vahinko aktivoimalla korjaava tai suojaava laite. Toiminnallinen turvallisuus tuotetaan aktiivisen järjestelmän avulla, esimerkiksi palo-ovea ei luokitella aktiiviseksi järjestelmäksi. Automaattinen tulen sammutus järjestelmä, joka tunnistaa tulipalon sa- vun perusteella ja aktivoi sprinklerit palon sammuttamiseksi luokitellaan aktiiviseksi järjestelmäksi. (IEC 2016.) Perinteisissä moottorinohjaussovelluksissa toiminnallinen turvallisuus on toteutettu taa- juusmuuttajan ulkopuolelle käyttämällä turvareleitä. Taajuusmuuttajaan integroitu toi- minnallinen turvallisuus helpottaa moottorinohjaussovellusten turvajärjestelmien toteut- tamista, koska sen avulla voidaan yksinkertaistaa turvajärjestelmää jättämällä pois pe- rinteisissä turvajärjestelmissä käytettäviä komponentteja. 7 Kuva 1 Perinteisen moottorinohjaussovelluksen turvajärjestelmä. (Siemens 2016a.) Kuvassa Kuva 1 on esitetty perinteinen moottorinohjaussovelluksen turvajärjestelmä ja kuvassa Kuva 2 moottorinohjaussovelluksen turvajärjestelmä, joka hyödyntää taajuus- muuttajaan integroitua toiminnallista turvallisuutta. (ABB 2016b; Meany 2016: 1361.) 8 Kuva 2 Taajuusmuuttajaan integroitu toiminnallinen turvallisuus osana moottorinoh- jaussovelluksen turvajärjestelmää. (Siemens 2016a.) IEC 61800-5-2 määrittää taajuusmuuttajien toiminnallisen turvallisuuden toteuttamiseen käytettäviä turvafunktioita, joita ovat esimerkiksi STO (Safe torgue off) ja SLS (Safety limited speed). (Meany 2016: 1362.) Kuvassa Kuva 3 on esitetty STO-turvafunktion toiminta. STO-turvafunktion avulla taa- juusmuuttajan ohjaaman sähkömoottorin pysäytetään estämällä taajuusmuuttajan tuot- taman sähköenergian pääsy sähkömoottoriin, jolloin sähkömoottori rullaa vapaasti py- sähdyksiin. STO-turvafunktiota käytetään esimerkiksi hätäpysäytyspainikkeen toteutta- miseen. (Siemens 2016b; Meany 2016: 1363.) 9 Kuva 3 Safe torgue Off -turvafunktio. (Meany 2016: 1363.) Kuvassa Kuva 4 on esitetty SLS-turvafunktion toiminta. SLS-turvafunktio avulla säh- kömoottorin nopeus pidetään asetetuissa rajoissa, jos sähkömoottorin nopeus ylittää asetetut rajat suoritetaan asetetut toimenpiteet. SLS-turvafunktion avulla voidaan esi- merkiksi rajoittaa sähkömoottorin pyörimisnopeus kuljettimen puhdistamisen ajaksi. (Meany 2016: 1363.) Kuva 4 Safely limited speed -turvafunktio. (Meany 2016: 1363.) 10 3 KETTERÄT MENETELMÄT Perinteiset ohjelmistokehitysmenetelmät, kuten vesiputousmalli suoriutuvat huonosti ohjelmistokehityksessä tilanteista, joissa vaatimukset muuttuvat. Ketterät ohjelmistoke- hitysmenetelmät koostuvat käytännöistä ja suoriutuvat paremmin muuttuvista vaatimuk- sista, koska ketterien ohjelmistokehitysmenetelmien käytännöt kasvattavat projektissa työskentelevien ihmisten kanssakäymistä. Tunnetuimpia ketteriä ohjelmistokehitysme- netelmiä ovat Scrum ja Extreme Programming. Yleisesti ohjelmistoprojekteissa käyte- tään ketteristä ohjelmistokehitysmenetelmistä muutamaa käytäntöä, koska käytäntöjen sisäistäminen on etujen saavuttamisen kannalta tärkeää. (Xiaodan & Stacie 2014: 912.) 3.1 Säännölliset tilannepalaverit käytäntö Säännölliset tilannepalaverit käytännössä projektitiimin jäsenet pitävä säännöllisin vä- liajoin tilannepalaverin, jossa keskustellaan projektin tilanteesta. Esimerkiksi Scrum- menetelmässä tilannepalavereja pidetään kerran päivässä. Scrum-menetelmän tilannepa- laverissä jokainen tiimin jäsen saa noin minuutin mittaisen puheenvuoron. (Lehtonen, Tuomivaara, Rantala, Känsälä, Mäkilä, Jokela, Könnölä, Kaisti, Suomi, Isomäki & Yli- toiva 2014: 43). 3.2 Iteraatio käytäntö Iteraatio käytännössä projektitiimin työ jaksotetaan vakio mittaisiin jaksoihin eli sprint- teihin. Jokaisen sprintin päätteeksi asiakkaalle toimitetaan julkaisu ohjelmistosta. Riip- puen sprintin pituudesta muutokset, joita yhden sprintin aikana saadaan aikaiseksi voi- vat vaihdella. Tavoite kuitenkin on, että jokaisen sprintin aikana pystytään esimerkiksi toteuttamaan vähintään yksi uusi ominaisuus ohjelmistoon. Sprinttien pituudet voivat 11 vaihdella projektin koon mukaan 1 viikosta 4 viikkoon. Iteraatio käytäntöä käytetään sekä Scrum, että Extreme Programming -menetelmissä. (Lehtonen ym. 2014: 4–6, 35). Scrum-menetelmässä sprintin sisältö suunnitellaan suunnittelupalaverissa projektitiimin jäsenet valitsevat priorisoidusta kehitysjonosta vaatimuksia, jotka halutaan toteuttaa sprintin aikana. Vaatimuksille annetaan työmääräarviot, joiden avulla projektitiimi pys- tyy päättelemään, kuinka paljon vaatimuksia sprintin aikana ehditään toteuttamaan. (Lehtonen ym. 2014: 37). Scrum-menetelmässä sprintin päätteeksi pidetään katselmointipalaveri, jossa käydään läpi suunnittelupalaverissa valitut vaatimukset ja vaatimusten tila. Asiakkaalle esitellään valmiit vaatimukset, joita asiakas kommentoi. Keskeneräisistä vaatimuksista käydään läpi syyt, miksei vaatimuksia ole ehditty toteuttamaan. Vaatimusten tilat päivitetään kehitysjonoon seuraavaan sprintin suunnittelupalaveria varten. (Lehtonen ym. 2014: 39). 12 4 OHJELMISTOARKKITEHTUURIT Ohjelmistoarkkitehtuuri asettaa rajat, joiden puitteissa ohjelmistoa tulisi ylläpitää ja kehittää. Ohjelmistoarkkitehtuuri määrittää säännöt joiden avulla ohjelmisto jaetaan komponentteihin, säännöt joiden avulla määritetään komponenttien väliset suhteet. Sääntöjen lisäksi ohjelmistoarkkitehtuuri määrittää ohjelmiston kehityksessä käytettävät suunnittelumallit. (Koskimies & Mikkonen 2005: 18–19.) 4.1 Kerrosarkkitehtuuri Kerrosarkkitehtuuri on yleinen malli, jonka avulla voidaan yksinkertaisesti esittää mo- nimutkaisemmankin ohjelmiston arkkitehtuuri jakamalla ohjelmiston komponentit tie- tyllä logiikalla kerroksiin. Kuvassa Kuva 5 on esitetty yksinkertainen kerrosarkkitehtuu- ri, jossa ylimpänä kerroksena on käyttöliittymä ja alimpana kerroksena tietokanta. (Koskimies & Mikkonen 2005: 130–131.) Kuva 5 Yksinkertainen kerrosarkkitehtuuri. (Koskimies & Mikkonen 2005: 128.) Yleisesti kerrosarkkitehtuuria käytetään toteuttamisen apuna niin, että ohjelmiston eri kerrosten komponentit sidotaan suoraan toisiinsa. Kerrosten sitominen toisiinsa aiheut- taa riippuvaisuuksia komponenttien välille vaikuttaen negatiivisesti ohjelmiston kom- ponenttien uudelleenkäytettävyyteen. Kuvassa Kuva 6 User interface library - 13 komponentilla on riippuvuudet Domain library -komponenttiin ja Data Access library - komponenttiin. (Seeman 2012: 31–41.) Kuva 6 Esimerkki komponenttien riippuvaisuuksista käytettäessä kerrosarkkitehtuuria. (Seeman 2012: 37.) 4.2 Suunnittelumallit ja periaatteet Suunnittelumallit ovat dokumentoituja hyviksi todettuja ratkaisuja yleisiin ohjelmisto- teknisiin ongelmiin. Suunnittelumallien käyttämisellä pyritään parantamaan ohjelmiston laatuominaisuuksia, joita ovat esimerkiksi testattavuus, muunneltavuus ja uudelleen- käytettävyys. Suunnittelumalli koostuu kolmesta osasta, jotka ovat ongelma, ongel- mayhteys ja ratkaisu. Ongelma on kuvaus ohjelmointikieliriippumattomasta yleisestä ohjelmiston suunnitteluongelmasta, joka ilmenee monenlaisissa järjestelmissä. Ongel- mayhteys määrittää tilanteen, jossa kyseistä suunnittelumallia on mahdollista käyttää ja ohjelmiston laatuominaisuuden, jota ratkaisun tulisi parantaa. Ratkaisu on luokkakaavio ja seliteteksti ongelman ratkaisusta sekä mahdollista lisäinformaatioita, esimerkiksi jos suunnittelumallin käyttö heikentää jotakin ohjelmiston laatuominaisuutta. (Koskimies & Mikkonen 2005: 102–105.) 14 Suunnitteluperiaatteet ovat hyväksi todettuja periaatteita, joita käyttämällä eliminoidaan suunnitteluvirheitä. Suunnitteluvirheet tunnistetaan oireiden perusteella, suunnitteluvir- heiden oireita ovat jäykkyys, hauraus, muuttumattomuus, tahmeus, turha monimutkai- suus, turha toistaminen sekä sameus. Yleensä suunnitteluvirheet johtuvat jonkin suun- nitteluperiaatteen laiminlyönnistä. (Martin 2003: 85–86.) Yksi yleisimmistä tavoista kahden tai useamman komponentin riippuvaisuuksien pois- tamiseen on rajapinnan määrittäminen komponenttien välille. Tätä tapaa Robert kutsuu Abstract Server -malliksi. Kuvassa Kuva 7 on esitetty yksinkertainen luokkakaavio, jossa Switch-luokka on riippuvainen Light-luokasta. Ongelmaksi tämä muodostuu siinä vaiheessa, kun Switch-luokkaa halutaan käyttää jonkin muun, kuin Light-luokan kans- sa. Kuvassa Kuva 8 on esitetty sama tilanne, mutta Switch ja Light -luokkien välinen riippuvuus on poistettu määrittämällä Switchable-rajapinta. (Martin 2003: 318.) Kuva 7 Switch ja Light -luokkien välinen riippuvuus. (Martin 2003: 318.) Kuva 8 Switch ja Light -luokan riippuvuus poistettu Switchable-rajapintaa käyttäen. (Martin 2003: 318.) 15 Toinen hyödyllinen suunnittelumalli luokkien välisten riippuvuuksien vähentämiseen on abstract factory -suunnittelumalli. Kuvassa Kuva 9 esitetty Some App -luokka on riip- puvainen Square ja Circle -luokista, koska Some App -luokka on vastuussa square ja circle -objektien luomisesta. Kuvassa Kuva 10 on Some App -luokan riippuvuudet square ja circle -luokkiin poistettu abstract factory -suunnittelumallin avulla. Kuvassa Kuva 10 square ja circle -objektien luominen on siirretty ShapeFactory-rajapinnan toteutukseen, jolloin Some App -luokalla in riippuvuus vain ShapeFactory-rajapintaan. Kuva 9 Some App -luokan riippuvuus Square ja Circle -luokkiin. (Martin 2003: 270.) Kuva 10 Some App -luokan square ja circle -luokkien riippuvuudet poistettu Abstract Factory -suunnittelumallin avulla. (Martin 2003: 270.) 16 Riippuvuusinversio suunnitteluperiaatetta (Dependency inversion principle) voidaan myös käyttää komponenttien välisten riippuvaisuuksien vähentämiseen. Suunnitteluvir- heiden oireista jäykkyys ja muuttumattomuus voidaan päätellä, että sisältääkö arkkiteh- tuuri komponenttien välisiä riippuvaisuuksia. Dependency Inversion -periaatetta (DIP) käytetään jäykkyyden ja muuttumattomuuden eliminointiin, jolloin sen käyttö vähentää riippuvaisuuksia ja parantaa muunneltavuutta. (Martin 2003: 85, 134.) Dependency inversion -periaate suosittelee käyttämään kahta heuristiikkaa, jotka ovat:  "High-level modules should not depend on low-level modules. Both should de- pend on abstractions." (Martin 2003: 127.)  "Abstractions should not depend on details. Details should depend on abstrac- tions." (Martin 2003: 127.) Dependency inversion -suunnitteluperiaate suosittelee määrittelemään rajapinnat ylem- män kerroksen vaatimusten mukaan. Kuvassa Kuva 11 on esitetty yksinkertainen ker- rosarkkitehtuuri, jossa ylemmät kerrokset riippuvat alemmista kerroksista. Kuvassa Ku- va 12 on määritetty rajapinnat ylemmän tason komponenttien tarpeiden perusteella ja alemman tason komponentit toteuttavat nämä rajapinnat. Kuva 11 Kerrosarkkitehtuuri, jossa kerrokset riippuvat toisistaan. (Martin 2003: 128.) 17 Kuva 12 Kerrosarkkitehtuuri, johon on sovellettu Dependency inversion -periaatetta. (Martin 2003: 129.) Dependency inversion -suunnitteluperiaate kieltää ylemmän tason komponentteja ole- masta riippuvaisia alemman tason komponenteista, suosittelee erottamaan komponent- tien toteutukset toisistaan rajapintojen avulla ja määrittelemään rajapinnat käyttävän komponentin näkökulmasta. (Martin 2003: 128–129.) Vakaat riippuvuudet suunnitteluperiaatetta (Stable Dependencies principle) voidaan käyttää komponenttien välisten riippuvaisuuksien optimointiin. Stable Dependencies - suunnitteluperiaate (SDP) suosittelee, että komponenttien tulisi olla aina riippuvaisia vakaammista komponenteista. Kuvassa Kuva 13 on esitetty komponentti X, joka on 18 vakaa komponentti. Komponentti X on vakaa, koska se ei ole riippuvainen mistään muusta komponentista ja kolme muuta komponenttia ovat riippuvaisia siitä. Kuvassa Kuva 14 on esitetty komponentti Y, joka epävakaa, koska se riippuu kolmesta muusta komponentista eikä mikään muu komponentti riipu siitä. Komponenttien muunnelta- vuus on päinvastainen komponentin vakauteen nähden, eli vakaammat komponentin ovat huonommin muunneltavia kuin epävakaat komponentit. (Martin 2003: 261, 263.) Kuva 13 Vakaa komponentti. (Martin 2003: 261.) Kuva 14 Epävakaa komponentti. (Martin 2003: 262.) 19 4.3 Portit ja adapterit -arkkitehtuuri Kerrosarkkitehtuurin käyttäminen aiheuttaa pitkällä aikavälillä kerrosten välisten rajo- jen hämärtymisen, joka johtaa koodin vuotamiseen vääriin kerroksiin. Riippuen kerros- ten toiminnallisuuden jaosta voi olla vaikeaa päättää että, mihin kerrokseen tietty toi- minnallisuus tulisi integroida. Kuvassa Kuva 15 on esitetty esimerkki sovelluksen eri kerroksista. Esimerkiksi Twitter syötteen käsittelyn integrointi kuvan Kuva 15 mukai- seen kerrosarkkitehtuuriin voitaisiin tehdä sekä presentation-kerrokseen, että data- kerrokseen. (Young 2017.) Kuva 15 Perinteinen kerrosten nimeämisen käytäntö. (Young 2017.) Hexagonal-arkkitehtuurissa yllä mainittuihin ongelmiin on pyritty löytämään ratkaisut eristämällä business logiikka (Application Domain) kuvan Kuva 16 esittämällä tavalla. Hexagonal-arkkitehtuuri tunnetaan myös nimellä portit ja adapterit -arkkitehtuuri. Mar- kin (Seeman 2013) mukaan kerrosarkkitehtuurin pystyy muuntamaan portit ja adapterit -arkkitehtuuriksi käyttämällä dependency inversion -suunnitteluperiaatetta (Young 2017; Cockburn 2005.) 20 Kuvasta Kuva 16 on poistettu kuvassa Kuva 15 olevat kerrokset Presentation ja Integra- tion. Kuvassa Kuva 16 business logiikka (Application Domain) sisältää mallin jonkin liiketoimintakohtaisen ongelman ratkaisuun eikä sillä ole riippuvaisuuksia ulkopuolelle. Komponentit kommunikoivat business logiikan kanssa porttien kautta, porteilla on kak- si tehtävää. Porttien ensimmäinen tehtävä on suojata business logiikkaa koodin vuota- miselta business logiikan ja komponenttien välillä. Porttien toinen tehtävä on varmistaa, että komponentit ryhmitellään käyttötarkoituksen mukaan. Portit määrittävät rajapinnat joiden kautta komponentit kommunikoivat business logiikan kanssa ja joiden kautta business logiikka kommunikoi komponenttien kanssa. Portit voidaan jakaa kahteen ryhmään ensisijaisiin ja toissijaisiin. Ensisijaisten porttien kautta komennetaan business logiikka suorittamaan jokin toiminto. Toissijaisten porttien kautta business logiikka komentaa komponentteja suorittamaan jonkin toiminnon. (Young 2017; Garrido de Paz 2018.) Kuva 16 Portit ja adapterit -arkkitehtuuri. (Young 2017.) 21 Komponentit, jotka kommunikoivat business logiikan kanssa porttien kautta kutsutaan sovittimiksi. Sovittimia on myös kahden tyyppisiä ensisijaisia ja toissijaisia. Ensisijaiset sovittimet käyttävät ensisijaisten porttien määrittämiä rajapintoja. Toissijaiset sovittimet toteuttavat toissijaisten porttien määrittämiä rajapintoja. Yhtä porttia kohden voi olla monia sovittimia. Portit ja adapterit -arkkitehtuuria voidaan käyttää hyväksi kuvan Kuva 17 mukaisesti testauksessa. Toteuttamalla user-side API -porttiin testipenkki-sovitin ja data-side API -porttiin mock-tietokanta -sovitin pystytään sovelluksen business-logiikan testaus automatisoimaan. (Young 2017; Cockburn 2005.) Kuva 17 Portit ja adapterit -arkkitehtuuri testauksessa. (Cockburn 2005.) 22 Portit ja adapterit -arkkitehtuuri jakaa ominaisuuksia tunnetuista arkkitehtuureista oh- jelmistokehyksien kanssa. Ohjelmistokehykset eivät itsessään ole suorituskelpoisia. Ohjelmistokehykset vaativat koodia kehyksen ulkopuolelta (Kuva 18), että kehyksestä saadaan suorituskelpoinen sovellus tai komponentti. Portit ja adapterit -arkkitehtuurissa ei business logiikka itsessään ole suorituskelpoinen. Portit ja adapterit -arkkitehtuurissa business logiikka vaatii vähintään toissijaisten porttien toteutukset (toissijaisen sovitti- men) ollakseen suorituskelpoinen komponentti ja myös ensisijaisia portteja käyttävän komponentin (ensisijaisen sovittimen) ollakseen suorituskelpoinen sovellus. Ohjelmis- tokehyksen erona portit ja adapterit -arkkitehtuuriin voidaan pitää sitä, että portit ja adapterit -arkkitehtuurissa business logiikka pitää olla eristetty rajapintojen avulla, oh- jelmistokehyksissä tätä rajausta ei suoranaisesti tehdä. (Koskimies & Mikkonen 2005: 190–192) Kuva 18 Ohjelmistokehyksen vaatimat toteutukset kehyksen ulkopuolelta. (Koskimies & Mikkonen 2005: 190.) 23 5 TUTKIMUSMENTELMÄ JA LÄHTÖTILANNE Tutkimusmenetelmänä päätettiin käyttää tapaustutkimusta, koska se soveltuu tosielämän ilmiöiden tutkimiseen. Tapaustutkimuksessa tutkitaan tosielämän ilmiötä ja se vastaa parhaiten tutkimuskysymyksiin, kuinka ja miksi. (Sjoberg, Dyba & Jorgensen 2007). Tutkimuksessa päätettiin tutkia projektissa toteutetun PC-työkalun business-logiikassa käytetyn portit ja adapterit -arkkitehtuurin soveltuvuutta ketterään ohjelmistokehityk- seen. Portit ja adapterit -arkkitehtuuri parantaa ohjelmiston ylläpidettävyyttä, joka on tärkeää ketterässä ohjelmistokehityksessä. Portit ja adapterit -arkkitehtuurin soveltu- vuutta ketterään kehitykseen päätettiin tutkia muunneltavuuden kautta seuraavien tutki- muskysymyksien avulla:  Parantaako portit ja adapterit -arkkitehtuuri ylläpidettävyyttä muunneltavuus komponentin kautta.  Miksi portit ja adapterit -arkkitehtuuri parantaa ylläpidettävyyttä, muunnelta- vuus komponentin kautta. Ensimmäiseen kysymykseen pyrittiin löytämään vastaus analysoimalla valittujen käyt- täjätarinoiden aikana tehtyä toteutusta. Käyttäjätarinat valittiin projektin alkupäästä, koska projektin alkupään aikana toteutettiin suurin osa tärkeimmistä komponenteista. Toteutuksen muunneltavuutta analysoitiin riippuvaisuuksien avulla, koska niin kuin aiemmin kappaleessa 4.2 todettiin suorat riippuvaisuudet kahden toteutusta sisältävän komponentin tai luokan välillä vaikuttavat negatiivisesti muunneltavuuteen. Toteutuk- sen muunneltavuutta analysoitiin yksinkertaistetulla versiolla Stephenin ja Pao-Shengin (Yau Chang 1988: 374) esittämästä muunneltavuuden mittaamisen mallista. Yksinker- taistetussa muunneltavuuden mittaus mallissa toteutuksen sisäistä ja ulkoista muunnel- tavuutta luokkien ja komponenttien välillä analysoitiin riippuvaisuuksien kautta. Sisäi- sellä muunneltavuudella tarkoitetaan luokkien välistä muunneltavuutta komponentin 24 sisällä ja ulkoisella muunnettavuudella komponenttien välistä muunneltavuutta. Muun- neltavuudella kuvataan muutosten tekemisen helppoutta komponenttiin ja todennäköi- syyttä sille, että muutos toisessa komponentissa aiheuttaa muutoksia muihin kom- ponentteihin. Toiseen kysymykseen pyrittiin löytämään vastaus vertailemalla PC- työkalun business-logiikan komponenttien välisiä riippuvaisuuksia Robertin (Martin 2003: 95–135, 253–268) mainitsemiin ketterien suunnitteluperiaatteiden asettamiin suo- situksiin. Ennen työn aloitusta projektia olivat vieneet eteenpäin kaksi muuta samassa projektissa työskentelevää kollegaa, projektin tilanne ennen työn aloitusta oli seuraava:  Käyttöliittymästä oli käyttöliittymä spesifikaatioiden mukainen toteutus olemas- sa, jossa näytettiin demo dataa. Käyttöliittymää pystyi testaamaan nettiselaimen kautta.  Business logiikan runko oli valmiina, joka tarkoitti, että käyttöliittymän ja busi- ness logiikan välisen rajapinnan toiminnot oli dokumentoitu samalle tasolle käyttöliittymän tarpeen kanssa, mutta toteutus puuttui business logiikasta. Busi- ness logiikan arkkitehtuuriksi oli valittu portit ja adapterit -arkkitehtuuri.  PC-työkalulla oli toimiva Windows asennusohjelma, johon oli toteutettu vain perusominaisuudet.  PC-työkalussa oli Windows komentorivi käyttöliittymä, jolla oli mahdollista la- data binääriformaatissa oleva turvafunktioiden parametri tiedosto taajuusmuutta- jalle.  Kommunikaatiokirjastoon oli toteutettu osa tarvittavista toiminnoista taajuus- muuttajan kanssa kommunikoimiseen.  Taajuusmuuttajan kommunikaatio rajapinta oli keskeneräinen. 25 Tämän työn tekijä työskenteli kahden projektissa olevan kollegan kanssa. Toisen kolle- gan vastuualue oli käyttöliittymän toteuttaminen. Toinen kollega avusti business logii- kan ja kommunikaatiokirjaston toteuttamisessa tarpeen mukaan. Projektissa käytettiin ketteriä ohjelmistokehitysmenetelmiä. Scrum-menetelmästä käy- tettiin sprintti ja säännölliset tilannepalaverit käytäntöä. Sprintin pituutena käytettiin kuutta viikkoa ja tilannepalavereita pidettiin kerran viikossa. Ajallisesti projekti kesti 12-kuukautta ja siihen mahtui 8-sprinttiä. Taulukossa Taulukko 1 on esitetty jokaisen sprintin sisältö käyttäjätarinoiden avulla ja kursivoitu käyttäjätarinat, joiden toteutusta käytettiin tutkimuksen materiaalina. 26 Taulukko 1 Yleiskuva projektin sprinttien(S) ja käyttäjätarinoiden(KT) sisällöstä S KT Kuvaus 1 1 Komentorivi liittymän perus rakenne ja parametritiedoston lataus komento. 1 2 Arkkitehtuurin suunnittelu ja PC-Työkalun rungon toteutus. 1 3 Diagnostiikka tiedon tallentaminen. 2 1 JSON-rajapinnan käyttöönotto käyttöliittymässä. 2 2 Parametritiedoston eri versioita tukevan rajapintarakenteen määrittäminen. 2 3 Parametritiedoston rakenteen ensimmäisen version toteutus. 2 4 JSON-rajapinnan toimintojen toteuttaminen Business logiikkaan. 2 5 Demo datan generointi ja taajuusmuuttajan simulointi. 3 1 JSON-rajapinnan yhteensopivuuden varmistaminen business logiikassa. 3 2 JSON-rajapinnan yhteensopivuuden varmistaminen käyttöliittymässä. 3 3 Taajuusmuuttajan kommunikaatioprotokollan toteutus kommunikaatiokirjas- toon. 3 4 Kommunikaatiokirjaston integrointi PC-työkaluun. 4 1 Parametritiedoston avaaminen ja tallentaminen pc:n tiedostojärjestelmään 4 2 Turvafunktioiden riippuvaisuuksien kuvaaminen parametritiedostossa. 4 3 Turvafunktioiden riippuvaisuuksien esittäminen käyttöliittymässä. 4 4 Loppujen komentorivi komentojen toteutus. 4 5 Yhteyden katkaiseminen laitteesta. 5 1 Toimintojen käsittelijöiden integraatiotestien toteutus. 5 2 Manuaalisten testitapausten dokumentointi. 5 3 Turvafunktioiden parametrien riippuvaisuuksien kuvaaminen parametritiedos- tossa. 6 1 Korjauksia käytettävyystesteihin. 6 2 Aktiivisuuslokin toteutus käyttöliittymään, 6 3 Aktiivisuuslokin toteutus business-logiikkaan. 6 4 Käyttöönottoraportin toteutus. 7 1 Laitetietojen liittäminen käyttöönottoraporttiin. 7 2 Raportoitujen bugien korjailua. 8 1 Aktiivisuuslokin tallennus tiedostoon. 8 2 Asennusohjelman viimeistely. 8 3 Käyttöönottoraportin tulostaminen. 27 Kuvassa Kuva 19 on esitetty ohjelmiston korkean tason rakenne kerrosarkkitehtuuria käyttäen. Graafisen käyttöliittymän (Web UI) toteutustekniikkana käytettiin Javascript- ohjelmointikieltä. Business logiikan ja kommunikaatiokirjaston toteutustekniikkana käytettiin C#-ohjelmointikieltä. Käyttöliittymän ja business logiikan välisessä rajapin- nassa käytettiin JSON (JavaScript Object Notation) -formaattia, joten rajapinta nimettiin JSON-rajapinnaksi. JavaScript Object Notation -formaatti on tekstimuotoinen ja sitä käytetään JavaScript-ohjelmointikielessä tiedon säilömiseen ja siirtoon. Business logii- kalla (Business Logic) viitataan kaikkiin muihin komponentteihin paitsi kommunikaa- tiokirjastoon (Communication Library) ja graafisen käyttöliittymän Web UI -osaan. Kuva 19 Ohjelmiston arkkitehtuuri esitettynä kerrosarkkitehtuuria käyttäen JavaScript-käyttöliittymä upotettiin C#-ohjelmointikielen tarjoamaan webview- käyttöliittymäkomponenttiin kuvan Kuva 20 mukaisesti. WebView-komponentti on sovellusalustakohtainen käyttöliittymäkomponentti, joka pystyy www-selaimen tavoin 28 suorittamaan javascript-ohjelmakoodia ja esittämään html-sisältöä. (Hazarika, Rahul, & Seshubabu 2014: 1589). Kuva 20 JavaScript käyttöliittymä WebView-komponentissa Kuvassa Kuva 21 on esitetty alkutilanne portit ja adapterit arkkitehtuuria käyttäen. Oh- jelmiston business-logiikkaan oli määritetty kolme porttia, jotka olivat Communication, Logging ja Interaction. Interaction-portin oli ensisijainen portti, jonka käyttötarkoitus oli välittää käyttäjän ko- mennot business logiikalle. Interaction-portiin oli aloitettu toteuttamaan kahta sovitinta, jotka olivat GUI-sovitin ja CLI-sovitin. CLI-sovittimen tehtävä oli tarjota käyttäjälle komentorivi käyttöliittymä. GUI-sovittimen tehtävä oli tarjota käyttäjälle JavaScript- ohjelmointikielellä toteutettu graafinen käyttöliittymä. Communication-portti oli toissijainen portti, jonka käyttötarkoitus oli mahdollistaa bu- siness logiikan kommunikointi taajuusmuuttajan kanssa. Communication-porttiin oli 29 aloitettu toteuttamaan Device-sovitinta, jonka tehtävä oli kommunikoida taajuusmuutta- jan kanssa käyttäen kommunikaatiokirjastoa. Kuva 21 Ohjelmiston alkutilanne esitettynä portit ja adapterit -arkkitehtuurilla. Logging-portti oli toissijainen portti ja sen käyttötarkoitus oli mahdollistaa diagnostiik- ka tiedon siirtäminen business logiikasta ulospäin. Logging-porttiin oli toteutettu kaksi sovitinta File ja UDP, koska kehitys käytössä diagnostiikka dataa haluttiin vastaanottaa reaaliajassa Log4Net-muodossa ja tuotanto käytössä diagnostiikka data haluttiin tallen- 30 taa tekstitiedostoihin. File-sovittimen tehtävä oli kirjoittaa diagnostiikka dataa määrät- tyyn tekstitiedostoon. UDP-sovittimen tehtävä oli lähettää diagnostiikka dataa käyttäen IP-pinon UDP-protokollaa ennalta määrättyyn osoitteeseen. UDP on yhteydetön IP- protokollan kuljetuskerroksen tiedonsiirto protokolla, jota käytetään esimerkiksi suora- toistopalveluissa videokuvan siirtämiseen. (IPv6 2017). Communication ja Interaction -porttien rajapintojen määrittäminen oli juuri aloitettu, mutta Logging-portin rajapinta oli valmis. Logging-portin sovittimien toteutukset File ja UDP olivat valmiit. Communication-portin Device-sovittimen, Interaction-portin GUI ja CLI -sovittimien toteutus oli juuri aloitettu. 5.1 Keskeneräiset portit ja sovittimet ennen työn aloitusta Interaction ja Communication -portteja ja sovittimia oli ehditty määrittämään hiukan ennen työn aloitusta. Logging-portin rajapinta oli valmis. Kuvissa Kuva 22 ja Kuva 23 on esitetty Interaction ja Logging -porttien rajapinnat ja niiden sisältämät funktiot työn aloitushetkellä. Interaction-portti tarjosi Kaksi rajapintaa, jotka olivat IDeviceFactory ja IDevice. IDeviceFactory-rajapinnan tehtävä oli luoda aktiivisia yhteyksiä laitteisiin ja IDevice-rajapinnan avulla laiteelle pystyi lataamaan binaarimuodossa olevan para- metritiedoston. Logging-portti tarjosi vain yhden rajapinna ILogger, jonka avulla muut komponentit pystyivät välittämään diagnostiikka dataa käyttäjille. CLI-sovittimesta käy- tettiin kaikkia interaction ja logging -porttien tarjoamia rajapintoja, mutta GUI- sovittimesta käytettiin vain IDeviceFactory-rajapinan GetBusNames-funktiota. 31 Kuva 22 Porttien tarjoamat rajapinnat työn aloitusvaiheessa. Kuva 23 porttien tarjoamien rajapintojen toiminnot työn aloitusvaiheessa. Kuvassa Kuva 24 on esitetty Communication-portin rajapinnat, jotka Device-sovitin toteuttaa käyttäen Communication library -komponenttia ja Logging-portin rajapinta, jonka toteuttavat File ja UDP -sovittimet. Interaction ja Communication -porttien raja- 32 pinnat olivat samat, koska työn aloitusvaiheessa niiden välille ei ollut vielä toteutettu mitään toiminnallisuutta. Kuva 24 Communication-portin Device-sovittimen toteutus ennen työn aloitusta. GUI-sovittimeen oli toteutettu peruslogiikka, jonka avulla Javascript käyttöliittymän komennot välitetään C# toiminnoille (Actions) ja toimintojen käsittelijöiden vastaukset välitetään takaisin käyttöliittymälle. Kuvassa Kuva 25 on esitetty GUI-sovittimen pää- komponentit Web UI, JS Native Bridge ja Service Facade. Web UI -komponentti sisältää Javascript-kielellä toteutetun käyttöliittymän, jonka tehtävä on välittää käyttäjän komennot JS Native Bridge -komponentin kautta Service Facade -komponentille. JS Native Bridge -komponentti mahdollistaa JavaScript ja C# -koodin välisen kommuni- kaation. Service Facade -komponentilla on kaksi tehtävää pyyntö JSON-objektien kä- sittely ja vastaus C#-objektien käsittely. Pyyntö JSON-objektien käsittelyssä pyyntö tyyppiset JSON-objektit muunnetaan C#-objekteiksi (Request-Dto) ja välitetään oikeal- le toiminnolle (Action) käsiteltäväksi. Vastaus C#-objektien (Response-Dto) käsittelys- sä C#-objektit muunnetaan JSON-objekteiksi ja välitetään takaisin JS Native Bridge - komponentille. 33 Kuva 25 GUI-sovittimen pääkomponentit Pyyntö JSON-objektit sisältävät kolme kenttää ID, CMD ja PARAMS. ID-kenttä sisäl- tää uniikin tunnisteen, jonka avulla vastaus pystytään linkittämään oikeaan pyyntöön. CMD-kenttä kertoo Service Facade -komponentille, että mille toiminnolle pyyntö lähe- tetään käsiteltäväksi. PARAMS-kenttä sisältää toimintokohtaiset parametrit. Vastaus JSON-objektit sisältävät kaksi kenttää ID ja RESPONSE. ID-kentän tehtävä on sama kuin pyyntöobjektilla. RESPONSE-kenttä sisältää toimintokohtaisen vastauksen. Toi- minnot käyttävät interaction-portin tarjoamia rajapintoja. 34 6 TYÖN OSUUS Seuraavissa kappaleissa käydään läpi aiemmin taulukossa Taulukko 1 esitellyistä käyt- täjätarinoista valitut ja analysoidaan niiden toteutuksen sisäistä ja ulkoista muunnelta- vuutta. 6.1 Parametritiedoston rakenne Toisen sprintin toisessa ja kolmannessa käyttäjätarinassa oli tarkoitus toteuttaa business logiikkaan tuki parametritiedoston rakenteen esittämiselle ja versioinnille. Parametritie- doston rakenne määritti turvafunktiot ja parametrit, joita PC-työkalulla pystyttäisiin konfiguroimaan. Asiakasvaatimuksen epäselvyyden vuoksi parametritiedoston raken- teen, ensimmäisen version toteutus ja rakenteen arvojen editointi toteutettiin business logiikan core logic -komponenttiin. Tämän lisäksi interaction-porttiin lisättiin tarvittavat rajapinnat parametriarvojen editointiin ja parametritiedoston rakenteen palauttamiseen. Parametrienarvojen lukemista ja kirjoittamista varten interaction ja communication - portteihin määritettiin IConfigurationContainer ja IConfigurationContainerFactory -rajapinnat, joiden kautta uuden parametritiedoston luonti ja parametrien arvojen luke- minen ja kirjoittaminen onnistuisi. Interaction-porttiin lisättiin myös IParameterStruc- tureService-rajapinta parametritiedoston rakenteen palauttamista varten käyttöliittymäl- le. Kuvassa Kuva 26 on esitetty Interaction-portin tarjoamat rajapinnat muutosten jäl- keen. 35 Kuva 26 Interaction-portin tarjoamat rajapinnat muutosten jälkeen Kuvassa Kuva 27 on esitetty IConfigurationContainer ja IConfigurationContainer- Factory -rajapintojen metodit. IConfigurationContainerFactory -rajapinnan Create- metodilla luodaan uusia instansseja IConfigurationContainer-rajapintojen toteutuksis- ta. Kuva 27 IConfigurationContainer ja IConfigurationContainerFactory -rajapintojen metodit Kuvassa Kuva 28 on esitetty tarkemmin parametritiedoston rakenteen rajapinnat inter- action-portissa ja toteutukset core logic -komponentissa. parametritiedoston rakenteen kuvaus koostuu kolmesta eri rajapinnasta IParameterStructureService-rajapinta, ISa- fetyFunction-rajapinta ja IParameter-rajapinta. 36 Kuva 28 Parametritiedoston rakenteen rajapinnat ja toteutus 37 IParameterStructureService-rajapinnalla on GetFunctions-metodi, joka palauttaa määritetyn parametrirakenteen. ISafetyFunction-rajapinta mahdollistaa eri turvafunkti- oiden määrittämisen, turvafunktioilla voi olla riippuvaisuuksia muihin turvafunktioihin ja yksittäisiin parametreihin. IParameter-rajapinta mahdollistaa turvafunktioiden pa- rametrien määrittämisen ja parametriarvojen sitomisen turvafunktioihin. Turvafunktioi- den parametrit käyttävät Communication-portin IConfigurationContainer-rajapintaa parametrin arvon lukemiseen ja kirjoittamiseen. Parametritiedoston rakenne -komponentin sisäinen toteutus on sidottu yhteen, joka tekee komponentin sisäisestä toteutuksesta vaikeasti muunneltavan. IParameterStructu- reService -rajapinnan toteutus riippuu STO ja SLS -turvafunktioiden toteutuksista, jot- ka riippuvat niiden parametrien toteutuksista. Muutokset turvafunktioiden parametreihin aiheuttavat todennäköisesti muutoksia turvafunktioiden toteutuksiin, koska turvafunkti- ot muodostuvat parametreista. Esimerkiksi muutos StoT1-luokan konstruktorin para- metreihin aiheuttaisi muutoksen STO-luokkaan, koska STO-luokka on vastuussa StoT1- objektin luomisesta, sama pätee STO ja ParameterStructureV0 -luokkien välillä. Parametritiedoston rakenne -komponentti riippuu vain Interaction portista, joten muu- tokset Parametritiedoston rakenne -komponenttiin eivät aiheuta muutoksia muihin kom- ponentteihin ja ainoastaan muutokset Interaction porttiin voivat aiheuttaa muutoksia Parametritiedoston rakenne -komponenttiin. Parametritiedoston rakenne -komponentin riippuvuus ainoastaan Interaction portista johtaa siihen, että komponenttitasolla Para- metritiedoston rakenne -komponentti on helposti muunneltava. Käytännössä helposti muunneltavuus tarkoittaa sitä, että muutos vain IConfigurationContainer-rajapinnasa voi aiheuttaa muutoksia turvafunktioiden parametreissa. Parameter structure -komponentin moduulitestit toteutettiin ParameterTests-luokaan, kuvassa Kuva 29 on esitetty ParameterTests-luokan riippuvaisuudet. Parameter struc- ture -testejä varten interaction-portin IConfigurationContainer-rajapinnasta luotiin Mock-toteutus (MockConfigurationContainer), jota käytettiin testeissä. Jokaiselle parametrille tehtiin Kaksi moduulitestiä, joista toinen testasi parametrin kirjoitus ja toi- nen parametrin lukua. Molemmissa testeissä tarkistettiin, että ParameterStructureV0- 38 objektin kautta löydetty tietyn id-arvon omaava IParameter-objekti vastasi tiettyä pa- rametria MockConfigurationContainer-objektissa. Kuva 29 Parameter structure -komponentin moduulitestien riippuvaisuudet Kuvissa Kuva 30 ja Kuva 31 on esitetty esimerkki sekvenssit parametrin arvon kirjoit- tamisen ja lukemisen moduulitesteistä. Sekvenssikaavioista on jätetty pois FindPara- meterDescription-funktion kuvaus koska se toimii testauksen apufunktiona ja sen teh- tävä on etsiä annetusta turvafunktiolistasta annetun turvafunktion id:n ja parametrin id:n perusteella testattava parametri. Myös ISafetyFunction-rajapinta on jätetty pois tilan säästämisen takia koska rajapinnan funktioita kutsutaan vain FindParameterDescripti- on-funktiosta. Parametriarvon kirjoittamisen testauksen sekvenssi oli seuraava:  Haetaan parametrirakenne ParameterStructureV0-objektilta ja etsitään testat- tava IParameter-objekti parametri rakenteesta kohdat 3.1 – 3.3 kuvassa Kuva 30  Kirjoitetaan parametrin arvo käyttämällä IParameter-objektin WriteValue- metodia ja tarkistetaan WriteValue-metodin paluuarvo kohdat 3.4 – 3.7 kuvas- sa Kuva 30  Luetaan parametrin arvo oletetusta MockConfigurationContainer-objektin kentästä ja tarkistetaan, että kirjoitettu arvo on päätynyt oikeaan kenttään MockConfigurationContainer-objektiin kohdat 3.8 – 3.11 kuvassa Kuva 30 39 Kuva 30 Esimerkki sekvenssi parametriarvon kirjoittamisen testauksesta Parametriarvon lukemisen testauksen sekvenssi noudatti samaa kaavaa kuin kirjoittami- sen poiketen tästä hieman:  Kohdat 3.1 ja 3.3 ovat samat kuin kirjoittamisessa. 40  Kirjoitetaan arvo oletettuun MockConfigurationContainer-objektin kenttään ja tarkistetaan kirjoituksen paluuarvo kohdat 3.4 – 3.7 kuvassa Kuva 31.  Luetaan parametriarvo IParameter-objektin ReadValue-funktiota käyttäen ja tarkistetaan että ReadValue-funktion palauttama arvo on sama kuin mitä kirjoi- tettiin MockConfigurationContainer-objektiin. Kuva 31 Esimerkki sekvenssi parametriarvon lukemisen testauksesta 41 6.2 Toimintojen käsittelijät Toisen sprintin neljännessä käyttäjätarinassa oli tarkoitus toteuttaa JSON-rajapinnan toiminnot PC-työkalun interaction-portin GUI-sovittimeen. Tavoitteena oli mahdollistaa käyttöliittymän kommunikointi business-logiikan kanssa. Taulukossa Taulukko 2 on esitetty JSON-rajapinnan toiminnot ja niiden kuvaukset. Taulukko 2 JSON-rajapinnan toiminnot ensimmäisen sprintin aikana Toiminto Kuvaus Vaihda salasana Vaihtaa taajuusmuuttajan salasanan. Yhdistä laitteeseen Muodostaa yhteyden taajuusmuuttajaan. Vie parametritiedosto Siirtää PC-työkalulla generoidun turvafunktioparametritiedos- ton taajuusmuuttajalle. Tuo parametritiedosto Hakee taajuusmuuttajalla olevan parametritiedoston. Hae yhteysväylät Palauttaa käytettävissä olevat taajuusmuuttajan kanssa kommu- nikointiin käytettävät kommunikaatioväylät. Hae parametritiedos- ton kuvaus Palauttaa parametritiedoston rakenteen, jonka avulla käyttöliit- tymän näkymät rakennetaan. Etsi laitteita Etsii taajuusmuuttajat joihin yhteys voidaan muodostaa. JSON-rajapinnan toimintojen toteuttaminen vaati muutoksia interaction-portin rajapin- toihin IDevice ja IDeviceFactory. kuvassa Kuva 32 on esitetty lisätyt rajapinnat ja nii- den metodit. Taulukossa Taulukko 3 on esitetty JSON-rajapinnan toimintojen käyttämät metodit interaction-portin rajapinnoista. 42 Kuva 32 IDevice ja IDeviceFactory -rajapintojen muutokset. Taulukko 3 JSON-rajapinnan toimintojen käyttämät interaction-portin metodit. Toiminto Rajapinta Metodi Vaihda salasana IDevice ChangePassword(...) Yhdistä laitteeseen IDeviceFactory ConnectToDevice(...) Vie parametritiedos- to IDevice IParameterFileStructureS… IConfigurationContainerFact… IParameter TransmitParameterFile(parameters..,) GetFunctions(…) Create(…) WriteValue(…) Tuo parametritiedos- to IDevice IParameterFileStructureS… IParameter ReadParameterFile(...) GetFunctions(…) ReadValue(…) Hae yhteysväylät IDeviceFactory GetBusNames(...) Hae parametritiedos- ton kuvaus IParameterFileStructureS… GetFunctions(…) Etsi laitteita IDeviceFactory ScanDevices(...) 43 GUI-sovittimen Service Facade -komponentissa oli valmius uusien toimintojen käsitte- lijöiden (Actions) toteuttamiseen periyttämällä uudet toiminnot ActionhandlerBase luokasta. Kuvassa Kuva 33 on esitetty yksityiskohtaisempi kuva Service Facade - komponentista. ActionhandlerBase-luokka tarjoaa toiminnoille mahdollisuuden pa- luuarvon välittämiselle takaisin Javascript käyttöliittymälle IResponseHandler- rajapinnan kautta. Kuva 33 Service Facade -komponentin luokkakaavio. Käyttöliittymältä saapuvat toimintojen suorituspyynnöt Saapuvat ServiceInteractor- luokalle, jonka vastuulla on aloittaa toiminnon suorittaminen IActionHandlerRegistry- rajapinnan avulla. IActionHandlerRegistry-rajapinnan toteutuksen vastuulla on pitää kirjaa kaikista toiminnoista, joita on mahdollista kutsua JSON-rajapinnan kautta. Jokai- selle JSON-rajapinnan toiminnolle määritettiin vastaava ActionHandlerBase-luokasta periytyvä toteutus ja määritettiin luokat, jotka kuvaavat pyyntö ja vastaus dto-objektit. Kuvassa Kuva 34 on esitetty yhdistä laitteeseen JSON-rajapinnan toiminnon toteutuk- sen luokkakaavio. Yhdistä laitteeseen toiminto toteutettiin ConnectToDrive-luokkaan, kuvassa Kuva 34 on esitetty ConnectToDrive-luokan riippuvuudet. ConnectToDrive-luokan tehtävänä on luoda yhteys käyttäen interaction-portin IDeviceFactory-rajapintaa ja välittää Con- nect-funktion palauttama IDevice-rajapinta ActiveConnectionDto-luokalle. 44 Kuva 34 ConnectToDrive-luokan riippuvuudet. 45 Kuvassa Kuva 35 on kuvattu ConnectToDrive-luokan moduulitestien toteutus. Moduu- litestit toteutettiin ConnectToDriveTests-luokkaan. ConnectToDrive-luokka on riip- puvainen IDeviceFactory ja ILogger -rajapinnoista. Logging-portille lisättiin Console- sovitin, jotta testien aikainen diagnostiikka data saatiin kaapattua talteen. Moduulites- teissä. IDeviceFactory-rajapinnan toteutus korvattiin Moq-kirjaston tynkä toteutuksella ja ILogger-rajapinnan toteutuksena käytettiin ConsoleLogger-luokkaa console- sovittimesta. Kuva 35 ConnectToDrive-luokan moduulitestien toteutus. ConnectToDrive-luokasta periytettiin ConnectToDriveTestHelper-luokka. Connect- ToDriveTestHelper-luokan tehtävä on paljastaa ExecuteAction-metodi testeille. Con- nectToDriveTests-luokka luo ConnecToDriveTestHelper-objektin välittäen IDevice- Factory-rajapinnan tynkä toteutuksen ja ConsoleLogger-objektin ConnectToDrive- objektille. ConnecToDriveTestHelper-objektin luonnin jälkeen objekti on valmis tes- tattavaksi. Moduulitestit määritettiin julkisiksi funktioiksi ConnectToDriveTests- luokkaan. Moduulitestien nimeämisessä sovellettiin Microsoftin suosituksia. Microsof- tin (Microsoft 2011) suosituksissa moduulitestin nimen tulisi sisältää neljä elementtiä, 46 jotka ovat luokan nimi, testattavat funktion nimi, odotettu käytös ja skenaario. Micro- softin suosituksista poiketen luokan nimi jätettiin pois testien nimistä, koska sitä ei näh- ty tarpeelliseksi. Muiden JSON-toimintojen moduulitestit toteutettiin vastaavalla taval- la, toiminto luokkien toteutusten riippuvuudet korvattiin Moq-kirjaston tynkä toteutuk- silla ja ILogger-rajapinnan toteutuksena käytettiin aina ConsoleLogger-luokkaa. Kuvassa Kuva 36 on esitetty yhden ConnectToDrive-luokan testin sekvenssi. Testin vaiheet ovat seuraavat:  Luodaan tarvittavat ConnectToDrive-riippuvuudet ja konfiguroidaan IDevice- Factory-rajapinnan mock-toteutus kohdat 1 – 3.  Luodaan ConnectToDriveTestHelper-objekti, ConnectToDriveRequest- objekti ja asetetaan portti parametri ConnectToDriveRequest-objektille kohdat 4 – 7.  Kutsutaan Execute-metodia ConnectToDriveTestHelper-objektilta ja annetaan ConnectToDriveRequest-objekti parametrina, tarkastetaan, että funktion pa- luuarvo ei ole null-tyyppinen kohdat 8 – 10. 47 Kuva 36 ConnectToDrive-testin sekvenssi. 48 Hae parametritiedoston kuvaus toiminto toteutettiin GetSafetyStructure-luokkaan, GetSafetyStructure-luokan riippuvuudet on esitetty kuvassa Kuva 37. GetSafe- tyStructure-luokan tehtävä on hakea parametritiedoston kuvaus käyttäen interaction- portin IParameterStructureService-rajapintaa, muuntaa parametritiedoston rakenne vastaus Dto-objekteiksi ja palauttaa vastaus Dto-objekti rakenne Service Facade- komponentille. Kuva 37 GetSafetyStructure-luokan riippuvuudet. 49 Muut toiminnot toteutettiin vastaavalla tavalla, eli toiminto käsittelee pyyntö dto - objektin, käyttää jotain metodeja interaction-portin rajapinnoista, tallentelee ja tai muut- taa jonkin sisäisen Dto-objektin tilaa ja palauttaa vastauksen Service Facade- komponentille. Toiminnot eivät ole riippuvaisi keskenään vaan tarvittavan informaation välitys toimintojen käsittelijöiden välillä hoidettiin Dto-objekteilla. Kuva 38 Toimintojen käsittelijöiden kommunikointi Dto-objektien kautta 50 Kuvassa Kuva 38 on esitetty toimintojen käsittelijöiden riippuvuudet Dto-objekteista. Projektin tässä vaiheessa toimintojen käsittelijät jakoivat vain yhden Dto-objektin Acti- veConnectionDto, jonka tehtävä on välittää aktiivista yhteyttä toimintojen käsittelijöi- den kesken. Toimintojen käsittelijöiden toteutukset GUI-sovittimessa ovat helposti muunneltavissa, koska niillä ei ole riippuvaisuuksia toisiinsa ja ne ovat riippuvaisia vain Interaction por- tin rajapinnoista. GUI-sovitin komponentti riippuu vain Interaction portista, joten GUI- sovitin on myös komponentti tasolla helposti muunneltava. Toimintojen käsittelijät ovat myös helposti moduulitestattavissa, koska niiden toteutukset riippuvat Dto-objekteista ja interaction-portin rajapinnoista. 6.3 Demo datan generointi Toisen sprintin viidennessä käyttäjätarinassa oli tarkoitus toteuttaa business logiikkaan demo datan generointi ja demo datan siirtäminen JSON-rajapinnan toimintojen kautta käyttöliittymälle. Tarkoitus oli simuloida taajuusmuuttajan toimintaa business logiikas- sa, jotta PC-työkalun testaaminen olisi mahdollista ilman yhteyttä taajuusmuuttajaan. Tavoite oli myös, että business logiikassa olisi helppo vaihdella toteutusta demo toteu- tuksen ja taajuusmuuttajan toteutuksen välillä. Demo ja taajuusmuuttajan -toteutuksen välinen helppo vaihdettavuus ratkaistiin määrittämällä communication-porttiin Demo- sovitin. Kuvassa Kuva 39 JSON-rajapinnan toimintojen käsittelijät, jotka on toteutettu Commands-komponenttiin käyttävät interaction-portin IConfigurationContainerFac- tory ja IDeviceFactory -rajapintoja, eivätkä ole tietoisia siitä kumpi sovittimista on käytössä. Tässä vaiheessa projektia communication ja interaction -portit olivat vielä niin lähellä toisiaan, ettei nähty tarpeelliseksi lähteä toteuttamaan kerrosta niiden väliin. 51 Kuva 39 Demo ja taajuusmuuttajan -toteutukset ja rajapinnat. IDeviceFactory ja IConfigurationContainerFactory -rajapintojen toteutukset Demo ja Device -sovittimissa luovat eri toteutuksia IDevice ja IConfigurationContainer - rajapinnoista kuvan Kuva 40 mukaisesti. Kuvassa Kuva 40 IDevice-rajapinta määrittää kommunikaatio operaatiot taajuusmuuttajalle kuten parametritiedoston kirjoittamisen ja lukemisen ja IConfigurationContainer -rajapinta määrittää operaatiot parametritiedos- ton käsittelyyn, kuten yksittäisen parametrin arvon kirjoittamisen ja lukemisen. 52 Kuva 40 IDeviceFactory ja IConfigurationContainerFactory toteutukset Demo ja Device -sovittimissa. 53 Kuvassa Kuva 41 on esitetty Demo-sovittimen toteutus. Kuva 41 Demo-sovittimen toteutus Demo-sovittimen sisäinen toteutus on sidottu tiukasti yhteen, josta seuraa, että kom- ponentin sisäisen toteutus on vaikeasti muunneltava. Komponentti riippuu vain commu- nication portista, joten Demo-sovitin on komponentti tasolla helposti muunneltava. 6.4 JSON-rajapinnan validointi Kolmannen sprintin ensimmäisessä käyttäjätarinassa oli tarkoitus kehittää tapa, jolla JSON-rajapinnan yhteensopivuus pystyttäisiin varmistamaan business logiikan ja käyt- töliittymän välillä. JSON-rajapinnan yhteensopivuus käyttöliittymän ja business logii- kan välillä varmistettiin määrittämällä JSON-rajapinnan toiminnoista rajapintakuvauk- set. Toimintojen rajapintakuvaukset sisälsivät toiminnon paluuarvon kuvauksen ja toi- minnon parametrien kuvaukset. Business logiikkaan toteutettiin moduulitestit jokaiselle JSON-rajapinnan toiminnon pyyntö ja vastaus -dto-objektille. Moduulitestit varmisti- vat, että business logiikan toimintojen paluuarvot ja parametrit vastasivat toimintojen rajapintakuvauksia. JSON-rajapinnan yhteensopivuuden varmistavia moduulitestejä kutsuttiin validaatio-testeiksi. Kuvassa Kuva 42 on esitetty JSON-rajapinnan validaatio- testien periaate. 54 Toimintojen rajapintakuvausten formaatiksi valittiin JSON-schema formaatti, koska useimmat JSON-kirjastot tukevat JSON-rakenteen eheyden varmistamista JSON- schema formaatin perusteella. JSON-schema formaatilla kuvataan haluttu JSON- rakenne. Kuva 42 JSON-rajapinnan validaatio-testien periaate. Toimintojen pyyntö ja vastaus dto-objektit testattiin kuvan Kuva 43 mukaisella sek- venssillä. Kaikkien pyyntö ja vastaus dto-objektien testaus noudatti samaa sekvenssiä yhdistä laitteeseen dto-objektien testauksen kanssa. Yhdistä laitteeseen dto-objektin testauksen sekvenssi oli seuraava: 1. Luo dto-objekti (ConnectToDriveRequest). 55 2. Aseta tarvittavat arvot dto-objektille. 3. Muunna dto-objekti JSON muotoiseksi tekstiksi. 4. Muunna dto-objektin JSON muotoinen teksti JObject-objektiksi. 5. Lataa dto-objektin JSON-schema. 6. Tarkasta dto-objektin eheys JObject-objektin IsValid metodia käyttäen. 56 Kuva 43 Yhdistä laitteeseen pyyntö dto-objektin testaus 57 6.5 Kommunikaatiokirjaston integraatio Kolmannen sprintin Neljännessä käyttäjätarinassa oli tarkoitus integroida kommunikaa- tiokirjasto PC-työkaluun. Käyttäjätarinan tavoitteena oli mahdollistaa PC-työkalu käyt- töliittymältä luodun parametritiedoston siirtäminen taajuusmuuttajalle ja taajuusmuutta- jalta ladatun parametritiedoston näyttäminen ja muokkaaminen käyttöliittymällä. Kommunikaatiokirjasto sisälsi taajuusmuuttajan protokolla toteutuksen, jonka avulla PC-työkalun taajuusmuuttajaa käyttävät toiminnot toteutettiin. Kommunikaatiokirjasto integroitiin PC-työkaluun kuvassa Kuva 44 näkyvään Device-sovittimeen. Kuva 44 Kommunikaatiokirjaston integraatioperiaate. Kuvassa Kuva 45 on esitetty tarkempi kuvaus Device-sovittimesta ja sen riippuvaisuuk- sista kommunikaatiokirjastoon. DriveContainerFactory, DriveContainer, DeviceFac- tory ja Device -luokat toteutettiin sovittimiksi, joiden avulla kommunikaatiokirjaston toteutukset integroitiin business logiikkaan. Device-sovittimen sisäinen toteutus on si- dottu tiukasti yhteen kommunikaatiokirjaston kanssa, joten sovittimen ulkoinen muun- neltavuus jäi välttävälle tasolle. Muutokset kommunikaatiokirjaston aiheuttavat hyvin todennäköisesti muutoksia Device-sovittimeen. Sisäinen muunneltavuus jäi kuitenkin hyvälle tasolle, koska esimerkiksi muutokset device-sovittimen Device ja DriveCon- 58 tainer -luokkiin eivät aiheuta muutoksia muihin Device-sovittimen luokkiin, koska nii- hin ei viitata suoraan mistään komponentin sisällä. Kuva 45 Kommunikaatiokirjaston riippuvuudet Device-sovittimessa. 6.6 Tulokset Analysoitujen käyttäjätarinoiden tuloksiksi saatiin toimiva integraatio käyttöliittymän, business-logiikan ja taajuusmuuttajan välille. GUI-sovittimeen toteutettiin toimintojen käsittelijät JSON-rajapinnan toiminnoille. Communication-porttiin toteutettiin Demo- sovitin ja Device-sovitin. Demo-sovitin generoi käyttöliittymälle demo dataa simuloi- 59 malla taajuusmuuttajan toimintaa, joka mahdollisti PC-työkalun käyttöliittymän testaa- misen business logiikan tuottamalla demo datalla. Device-sovittimen tehtävä oli mah- dollistaa parametritiedoston siirtäminen PC-työkalun ja taajuusmuuttajan välillä. Mo- duulitestien määritysten yhteydessä Communication-portin sovittimena käytettiin Mock-sovitinta, jonka toteutus generoitiin ajon aikaisesti käyttäen Moq-kirjastoa. Core Logic -komponenttiin toteutettiin ensimmäinen versio parametritiedoston rakenteesta. Logging-porttiin toteutettiin Console-sovitin, joka mahdollisti diagnostiikka datan ke- räämisen testejä ajettaessa. Kuva 46 Arkkitehtuuri käyttäjätarinoiden toteutuksen jälkeen. 60 Taulukkoon Taulukko 4 on kerätty toteutettujen komponenttien sisäiset ja ulkoiset muunneltavuudet. Kuvasta Kuva 46 nähdään komponenttien väliset riippuvaisuudet GUI-sovitin käyttää Interaction -porttia, eikä riipu muista komponenteista. Demo- sovitin toteuttaa Communication-portin eikä riipu muista komponenteista. Device- sovitin toteuttaa Communication-portin ja käyttää kommunikaatiokirjasto- komponenttia. Parameter Structure -komponentti toteuttaa Integration-portin rajapintoja ja käyttää Communication-porttia. Demo-sovittimen ja Parameter Structure - komponentin sisäiset toteutukset olivat tiukasti sidottu toisiinsa, josta seurasi, että De- mo-sovittimen ja Parameter Structure -komponentin sisäinen muunneltavuus jäi huonol- le tasolle. GUI-sovittimen sisäinen toteutus oli hyvin eroteltu, joka puolestaan johti sii- hen, että komponentin sisäinen muunneltavuus jäi hyvälle tasolle. Device-sovittimen sisäinen muunneltavuus jäi hyvälle tasolle, koska sen sisäisillä luokilla on hyvin vähän riippuvaisuuksia keskenään. Device-sovittimen ulkoinen muunneltavuus jäi välttävälle tasolle, koska se on eriytetty muusta sovelluksesta rajapintojen avulla, mutta on kuiten- kin samanaikaisesti tiukasti sidottu kommunikaatiokirjastoon. Kaikkien toteutettujen komponenttien paitsi Device-sovittimen ulkoinen muunneltavuus saavutti hyvän tason, koska komponentit eivät ole riippuvaisia toisistaan, vaan riippuvat ainoastaan Core Lo- gic -komponenttiin määritetyistä rajapinnoista. Taulukon Taulukko 4 voidaan tulkita, että portit ja adapterit -arkkitehtuurin käytöllä saavutettiin lähes hyvä ulkoinen muun- neltavuus ja välttävä sisäisen muunneltavuus, josta voidaan päätellä, että portit ja adap- terit -arkkitehtuurin käyttö parantaa ulkoista muunneltavuutta. Taulukko 4 Komponenttien sisäinen ja ulkoinen muunneltavuus Komponentti Sisäinen muunnelta- vuus Ulkoinen muunnelta- vuus GUI-sovitin Hyvä Hyvä Demo-sovitin Huono Hyvä Parameter structure -komponentti Huono Hyvä Device-sovitin Hyvä Välttävä 61 Toiseen tutkimuskysymykseen pyrittiin löytämään vastauksia kuvan Kuva 47 avulla. Kuvassa Kuva 47 on esitetty komponenttien väliset riippuvaisuudet, mutta kuvasta on jätetty pois sovittimien riippuvuudet kolmannen osapuolen komponentteihin selkeyden vuoksi. Todellisuudessa kaikki muut sovittimet paitsi Demo-sovitin riippuvat muista komponenteista, esimerkiksi Device-sovitin riippuu kommunikaatiokirjastosta, CLI- sovitin riippuu Windowsin komentorivi integraatioista ja niin edelleen. Alla olevasta kuvasta voidaan tehdä seuraavia havaintoja: 1. Kaikki komponentit riippuvat (viittaavat) Core-komponenttiin, jossa on määri- tettynä abstraktiot, joita muut komponentit toteuttavat tai käyttävät. 2. Kaikki komponentit viittaavat ulkoa sisäänpäin, jos huomioon ei oteta sovitti- mien riippuvaisuuksia kolmannen osapuolen komponentteihin. 3. Ainoastaan Composition-komponentti on riippuvainen kaikista komponenteista, koska sen tehtävänä on rakentaa koko sovellus. Sovelluksen rakentaminen tar- koittaa toteutusten sitomista abstraktioihin ja abstraktio viittausten välittämistä muille komponenteille. Composition-komponentin tehtävä on esimerkiksi päät- tää, mitä kolmesta Logging-portin toteutuksesta käytetään File, Console vai UDP. 62 Kuva 47 Komponenttien väliset riippuvuudet Vertailemalla yllä mainittuja havaintoja Robertin (Martin 2003: 95–135, 253–268) kä- sittelemiin ketteriin suunnitteluperiaatteisiin huomataan, että portit ja adapterit - arkkitehtuurista löytyy yhtenäisyyksiä SDP ja DIP suunnitteluperiaatteisiin, jotka Ro- bertin (Martin 2003: 134, 264) mukaan parantavat muunneltavuutta. Stable Dependencies -suunnitteluperiaate (SDP) suosittelee, että komponentit ovat riip- puvaisia vakaammista komponenteista, joka on yhtenäinen toisen yllä mainitun havain- non kanssa, jossa komponentit viittaavat ulkoa sisäänpäin. SDP vastaa ulkopuolelta si- säänpäin viittaamista, koska kuvan Kuva 47 mukaisessa arkkitehtuurissa ytimen keskel- le päätyvät keskeisimmät rajapinnat ja keskeisin toteutus mitkä luonnollisesti ajan kulu- essa muuttuvat vakaimmiksi. 63 Dependency Inversion -suunnitteluperiaate (DIP) kieltää ylemmän tason komponentteja olemasta riippuvaisia alemman tason komponenteista, suosittelee erottamaan kompo- nenttien toteutukset toisistaan rajapintojen avulla ja määrittelemään rajapinnat käyttävän komponentin näkökulmasta. DIP on osittain yhtenäinen ensimmäisen havainnon kanssa, koska ensimmäisessä havainnossa komponentit ovat riippuvaisia vain abstraktioista poikkeuksena Composition-komponentti, joka vastaa DIP suositusta erottelemaan kom- ponentit toisistaan rajapintojen avulla. Havainto puoltaa Markin (Seeman 2013) mainin- taa siitä, että portit ja adapterit -arkkitehtuuri perustuu dependency inversion - suunnitteluperiaatteen käyttöön. Portit ja adapterit -arkkitehtuurin yhtenäisyydet SDP ja DIP -suunnitteluperiaatteisiin voi hyvinkin selittää miksi portit ja adapterit -arkkitehtuuri näyttää parantavan ulkoista muunneltavuutta. 64 7 JOHTOPÄÄTÖKSET Tutkimuskohteena käytetyn projektin tuloksiksi saatiin asiakasvaatimukset täyttävä PC- työkalu taajuusmuuttajan toiminnallisen turvallisuuden konfigurointiin. Portit ja adapte- rit -arkkitehtuurin käytöllä PC-työkalun business logiikassa saavutettiin välttävä sisäi- nen muunneltavuus ja hyvä ulkoinen muunneltavuus. Tutkimuksen tuloksena saatiin näyttöä siitä, että portit ja adapterit -arkkitehtuuri soveltuu käytettäväksi ketterässä oh- jelmistokehityksessä, koska se parantaa ylläpidettävyyttä ylläpidettävyyden testattavuus komponentin lisäksi myös muunneltavuus komponentin kautta. Portit ja adapterit -arkkitehtuurin käytöstä aiheutuva hyvä ulkoinen muunneltavuus joh- tuu siitä, että arkkitehtuurissa sovelluksen keskeinen toiminnallisuus eristetään rajapin- tojen avulla muista komponenteista. Keskeisen toiminnallisuuden eristämisen toteutus täyttää osittain ketterien suunnitteluperiaatteiden suosituksia, joka aiheuttaa tuloksissa mainitut yhtenäisyydet arkkitehtuurin ja SDP ja DIP -suunnitteluperiaatteiden välillä. Tulosten perusteella voidaan päätellä, että portit ja adapterit -arkkitehtuurin käyttö nou- dattaa SDP-suunnitteluperiaatteita täysin ja DIP-suunnitteluperiaatetta osittain. Portit ja adapterit -arkkitehtuurin osittainen samankaltaisuus DIP-suunnitteluperiaatteeseen joh- tuu siitä, että DIP-suunniteluperiaate suosittelee määrittämään rajapinnat käyttävän komponentin näkökulmasta, kun taas portit ja adapterit -arkkitehtuuri ei ota kantaa raja- pintojen määrittämisen näkökulmaan, vaan vastuu tästä päätöksestä jätetään arkkiteh- tuurin käyttäjälle. Portit ja adapterit -arkkitehtuurin käytöstä aiheutuva välttävä sisäinen muunneltavuus johtuu siitä, että portit ja adapterit -arkkitehtuuri ei ota kantaa ensisijais- ten ja toissijaisten sovitin-komponenttien sisäiseen rakenteeseen, vaan jättää vastuun arkkitehtuurin käyttäjälle. Tutkimuksen tarkkuuteen voi vaikuttaa analyysiin valittujen käyttäjätarinoiden määrä, valitut käyttäjätarinat ja objektiivisuuden taso. Analyysiin valittiin kuusi käyttäjätarinaa projektin alkupäästä. Käyttäjätarinoiden määrä olisi voinut ehkä olla hieman suurempi tai sitten käyttäjätarinoita olisi voinut valita laajemmalta alueelta, esimerkiksi projektin 65 alkuosasta, keskiosasta ja loppuosasta. Käyttäjätarinoiden valinta laajemmalta alueelta olisi ehkä aiheuttanut arkkitehtuurin kokonaiskuvan hämärtymisen, mutta toisaalta olisi ollut hyvä, jos valituissa käyttäjätarinoissa olisi ollut mukana muutoksia aikaisemmin toteutettuihin komponentteihin. Muutoksien toteuttaminen olemassa oleviin komponent- teihin olisi näyttänyt todelliset muutosten tarpeet muissa komponenteissa. Tutkimusta tehdessä pyrittiin ottamaan mahdollisimman objektiivinen näkökulma, mutta koska tut- kimuksen tekijä on ollut mukana tutkimusmateriaalina käytetyssä projektissa, täytyy tämä ottaa huomioon tulosten tulkinnassa. Jatkotutkimuksena ehdotetaan portit ja adapterit -arkkitehtuurin vertailua Robertin (Martin 2003: 95–135, 253–268) mainitsemiin ketteriin suunnitteluperiaatteisiin esi- merkiksi ohjelmistosuunnittelijan sisäistämisen näkökulmasta. Kaiken kaikkiaan Mark mainitsee kirjassa 11 erilaista suunnitteluperiaatetta mukaan lukien SDP ja DIP olisi mielenkiintoista tietää kuinka suuri ero on portit ja adapterit -arkkitehtuurin sisäistämi- sessä verrattaessa 11:sta ketterän kehityksen suunnitteluperiaatteeseen sekä kuinka pal- jon enemmän arvoa 11:sta suunnitteluperiaatteen noudattaminen tuo ketterään ohjelmis- tokehitykseen verrattuna portit ja adapterit -arkkitehtuuriin. 66 LÄHDELUETTELO ABB (2016a). Drives deliver safety for food and beverage machinery [Verkkodoku- mentti]. ABB. [Viitattu 5.12.2016]. Saatavissa: http://new.abb.com/drives/segments/food-and-beverage/drives-deliver-safety-for-food- and-beverage ABB (2016b). Cost and time savings with drive-based functional safety [Verkkodoku- mentti]. ABB. [Viitattu 22.12.2016]. Saatavissa: http://new.abb.com/drives/functional- safety/cost-and-time-savings-with-drive-based-functional-safety Cockburn, A. (2005). Hexagonal architecture. [Verkkodokumentti]. Cockburn, A. [Vii- tattu 28.10.2018]. Saatavissa: https://web.archive.org/web/20180822100852/http://alistair.cockburn.us/Hexagonal+arc hitecture Cockburn, A. (2007). Agile Software Development. The Cooperative Game. Second Edition. Boston: Pearson Education. Inc. ISBN 0-321-48275-1 Garrido de Paz, JM. (2018). Ports and Adapters Pattern (Hexagonal Architecture). [Verkkodokumentti]. Garrido de Paz, JM. [Viitattu 21.12.2018]. Saatavissa: https://softwarecampament.wordpress.com/portsadapters/ Hazarika, P., Rahul, R. CP. & Seshubabu, T. (2014). Recommendations for Webview Based Mobile Applications on Android. In: 2014 IEEE International Conference on Advanced Communication Control and Computing Technologies (ICACCCT), 1589- 1592. Ramanathapuram: IEEE. Saatavissa: http://ieeexplore.ieee.org.proxy.uwasa.fi/document/7019375 IEC (2016). Functional Safety [Verkkodokumentti]. IEC. [Viitattu 22.12.2016]. Saata- vissa: http://www.iec.ch/functionalsafety/explained/ 67 ISO/IEC 25023 (2016). (SQuaRE) - Measurement of system and software product quality. Systems and software engineering - Systems and software Quality Require- ments and Evaluation. IPv6 (2017). UDP User Datagram Protocol. [verkkodokumentti]. Ipv6.com Inc. [Vii- tattu 6.7.2017]. Saatavissa: http://ipv6.com/articles/general/User-Datagram- Protocol.htm Koskimies, K. & Mikkonen, T. (2005). Ohjelmistoarkkitehtuurit. Tampere: Talentum. Lehtonen, T., Tuomivaara, S., Rantala, V., Känsälä, M., Mäkilä, M., Jokela, T., Könnö- lä, K., Kaisti, M., Suomi, S., Isomäki, M & Ylitoiva, M. (2014). Sulautettujen järjestel- mien. Ketterä käsikirja. Turku: Turun yliopisto. ISBN 978-951-29-5838-2 Martin, C. R. (2003). Agile Software Development. Principles, Patterns and Practices. New York: Pearson Education. Inc. ISBN 0-13-597444-5 Meany, Tom (2016). Functional safety for integrated circuits used in variable speed drives. In: PCIM Europe 2016, 1361-1368. Berlin: VDE. Saatavissa: http://ieeexplore.ieee.org.proxy.uwasa.fi/document/7499513 Microsoft (2011). General Service Testing Best Practices [Verkkodokumentti]. Micro- soft. [Viitattu 9.7.2018]. Saatavissa: https://msdn.microsoft.com/en- us/library/hh323702(v=vs.100).aspx Piper, James (2009). The Benefits of VFDs In HVAC Systems [Verkkodokmentti]. Faci- litiesNet. [Viitattu 21.12.2016]. Saatavissa: http://www.facilitiesnet.com/hvac/article/The-Benefits-of-VFDs-In-HVAC-Systems- Facilities-Management-HVAC-Feature--11278# 68 Siemens (2016a). Drive Technology Advantages [Verkkodokumentti]. Siemens. [Viitat- tu 22.12.2016]. Saatavissa: http://www.industry.siemens.com/topics/global/en/safety- integrated/machine-safety/product-portfolio/drive-technology/Pages/safety-drives.aspx Siemens (2016b). Safe stopping functions [Verkkodokumentti]. Siemens. [Viitattu 19.03.2017]. Saatavissa: http://www.industry.siemens.com/topics/global/en/safety- integrated/machine-safety/product-portfolio/drive-technology/Pages/safety- drives.aspx?tabcardname=functions Seeman, M. (2012). Dependency Injection in .NET. New York: Manning. ISBN 9781935182504 Seeman, M. (2013). Layers, Onions, Ports, Adapters: it's all the same. [Verkkodoku- mentti]. Seeman, M. [Viitattu 10.07.2018]. Saatavissa: http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same/ Sjoberg, D. I. K., Dyba, T. & Jorgensen, M. (2007). The Future of Empirical Methods in Software Engineering Research. In: Future of Software Engineering, 2007, 358-378. Minneapolis: IEEE. Saatavissa: http://ieeexplore.ieee.org.proxy.uwasa.fi/document/4221632/ Yau, S. S. & Chang, P. (1988). A metric of modifiability for software maintenance. In: Proceedings. Conference on Software Maintenance, 1988, 374-381. Scottsdale: IEEE. Saatavissa: https://ieeexplore-ieee-org.proxy.uwasa.fi/document/10190/ Young, C. (2017). Hexagonal Architecture–The Great Reconciler?. [Verkkodokument- ti]. Young, C. [Viitattu 26.5.2017]. Saatavissa: http://geekswithblogs.net/cyoung/archive/2014/12/20/hexagonal-architecturendashthe- great-reconciler.aspx 69 Xiaodan. Y & Stacie. P. (2014). Understanding agile software development practices using sharedmental models theory. Information and Software Technology 56: 6, 911- 921. Saatavissa: http://dx.doi.org.proxy.uwasa.fi/10.1016/j.infsof.2014.02.010