Ohjelmistoarkkitehtuurin suunnitteluperiaatteita Luento 2 12.9.2017 581358 Ohjelmistoarkkitehtuurit 1
Oppimistavoitteet Arkkitehtuuritiedon lähteet Yleisiä suunnitteluperiaatteita Information hiding Single Responsibility Principle Coupling & Cohesion Järjestelmän osittaminen Component Coupling & Cohesion Dependency Inversion Arkkitehtuurityyli ja patterni Peruskäsitteet 12.9.2017 581358 Ohjelmistoarkkitehtuurit 2
ARKKITEHTUURITIEDON LÄHTEET 12.9.2017 581358 Ohjelmistoarkkitehtuurit 3
Ohjelmistoarkkitehtuuritiedon lähteillä Yhdellä (yliopisto-) kurssilla ei kenestäkään kouluteta ohjelmistoarkkitehtia Ohjelmistoarkkitehdiksi kasvetaan kokemuksen ja haastavien tehtävien kautta Muitten kokemuksesta voi kuitenkin ottaa oppia ja kehittää tietojaan ja suunnittelutaitojaan Yleiset ohjelmistojen suunnitteluperiaatteet Laatuominaisuuksien suunnittelutaktiikat Arkkitehtuurityylit ja -patternit Kokemusraportit ja kuvaukset onnistuneista ja epäonnistuneista kehitysprojekteista (blogit, kirjat) 12.9.2017 581358 Ohjelmistoarkkitehtuurit 4
Kuningas näkee pelin toisin 12.9.2017 http://img.yle.fi/urheilu/jalkapallo/article6978622.ece/alternates/w580/studiokuva%20litmanen%20kuusela.jpg 581358 Ohjelmistoarkkitehtuurit 5
R.C. Martin Referenssejä D. Spinellis, G. Gousios: M. Fowler Prentice Hall, 2017 L. Bass, P. Clements, R. Kazman: I. Mistrik, A. W. Brown, M. Ali Babar O Reilly, 2009 Elsevier /Morgan Kaufmann, 2013 Pearson, 2003 Addison-Wesley Prof., 2012 http://martinfowler.com/eaacatalog/ 12.9.2017 581358 Ohjelmistoarkkitehtuurit 6
Lisää referenssejä Microservices.io http://microservices.io/ Patternikieli mikropalveluarkkitehtuurin käyttöön High Scalability sivusto http://highscalability.com/ Real Life Architectures tarinoita ja kokemuksia Erityisesti web-sovellusten ja palvelujen rakentajille Pilvessä tapahtuvan tietojenkäsittelyn perusteet patternien muodossa http://www.cloudcomputingpatterns.org Kirjan voi lukea SpringerLink e-kirjastossa ja ladata sieltä pdf:nä (kuuluu yliopiston tilaukseen) 12.9.2017 581358 Ohjelmistoarkkitehtuurit 7
YLEISET SUUNNITTELUPERIAATTEET 12.9.2017 581358 Ohjelmistoarkkitehtuurit 8
Yleiset suunnitteluperiaatteet Abstraction, Encapsulation, Inofrmation Hiding, Modularization, Separation of Concerns, Coupling and Cohesion, Sufficiency-Completeness-Primitiveness, Separation of Policy and Implementation, Single Point of Reference, Divide-and-Conquer, SOLID Principles, Katso esimerkiksi Luku 6.3 Enabling techniques for software architecture teoksessa Buschmann F. & al.: Pattern-Oriented Software Architecture, vol. 1. Wiley, 2001 Wikipedia http://en.wikipedia.org/wiki/list_of_software_developme nt_philosophies 12.9.2017 581358 Ohjelmistoarkkitehtuurit 9
Information Hiding Parnas, D.: On the Criteria to Be Used in Decomposing Systems Into Modules. Comm. ACM 15(12), 1972 Ohjelmisto jaetaan moduuleihin siten, että kukin moduuli kätkee jonkin todennäköisesti muuttuvan teknisen tai sovellusalueen piirteen toteutuksen (= suunnittelupäätökset) Moduuli tarjoaa palveluihinsa vakaan abstraktin rajapinnan, joka ei paljasta toteutuksen yksityiskohtia (~abstrakti tietotyyppi) Moduuli = ohjelman (erillinen) osa, joka sisältää yhteen kuuluvia elementtejä, esim. Java-pakkaus ja sen luokat; vaihdettava/uudelleen käytettävä (staattinen) rakenneosa (koodia, konf. tiedostoja tms.) Käytännössä Komponentti sisältää 1 n Moduulia Komponentti on sellaisenaan käyttövalmis järjestelmän osa https://en.wikipedia.org/wiki/modular_programming 12.9.2017 581358 Ohjelmistoarkkitehtuurit 10
Information Hiding Kun moduulin kätkemiä suunnittelupäätöksiä muutetaan, moduulia käyttäviä muita ohjelmiston osia ei tarvitse muuttaa, koska ne riippuvat vain samana pysyvästä rajapinnasta Useimmat ohjelmistokehittäjät pitävät itsestäänselvyytenä, että rajapinta (esim. Java-olion) ei paljasta olion toteutuksen yksityiskohtia Kentät merkitään yksityisiksi (private), mutta määritellään näkyviksi tarkoitetuille kentille (property) julkiset get() ja set() metodit Harvempi kuitenkaan tulee ajatelleeksi odotettavissa olevia muutoksia ja muutosten heijastusvaikutusten ennalta ehkäisemistä ohjelmiston modularisoininnin avulla Arkkitehdin työn kuvaan tällaisen ajatteleminen kuitenkin kuuluu Muutostarpeita voi tosin olla vaikea arvata etukäteen Tähän ongelmaan tepsii, paitsi oikein tehty olioperustainen suunnittelu, seuraavaksi esiteltävä periaate 12.9.2017 581358 Ohjelmistoarkkitehtuurit 11
Separation of Concerns Erilaiset tai yhteenkuulumattomat vastuut (responsibilities) on erotettava toisistaan ohjelmistossa Jaettava eri rakenneosille (luokka, moduuli); jokaisella on selkeä tehtävä Vastuu: jotakin mitä osa tekee tai tietää tai piilottaa muilta (toiminto, riippuvuus, data, ) Tietyn tehtävän yhteistyössä suorittavat osat on pidettävä erillään osista, jotka suorittavat muita tehtäviä Jos esimerkiksi komponentilla on useita rooleja (rajapintoja) eri tilanteita ja käyttöyhteyksiä varten, roolit on pidettävä itsenäisinä ja erillään komponentin sisällä 12.9.2017 581358 Ohjelmistoarkkitehtuurit 12
SRP Esimerkiksi Single Responsibility Principle, eli A class should have one and only One Reason to Change (ORC) kokoaa edellä mainitut periaatteet yhteen olioluokkien suunnitteluperiaatteeksi Yksi SOLID periaatteista https://en.wikipedia.org/wiki/solid_(objectoriented_design) Usein väärin ymmärretty tarkoittavan, että luokka saisi tehdä vain yhden asian - yhden asian periaate koskee luokan metodeja Vastuu on tässä laajempi käsite, joka liittyy ohjelmiston toiminnallisuuteen (laajasti ymmärrettynä) 12.9.2017 581358 Ohjelmistoarkkitehtuurit 13
SRP Luokka on vastuusta vain tietystä ohjelmiston toiminnallisuudesta Vastuu on kokonaisuudessaan kapseloitu (encapsulated) luokkaan Luokan tarjoamat palvelut (rajapinta) rajoittuvat tiukasti vain tähän vastuuseen 12.9.2017 581358 Ohjelmistoarkkitehtuurit 14
SRP-esimerkki Ajatellaan luokkaa, joka koostaa sovelluksen käsittelemästä datasta tulostettavan raportin Kuinka monesta syystä luokkaa voidaan joutua muuttamaan? Raportin sisältöä halutaan muuttaa (uutta dataa tai uusia laskelmia) Tulosteen ulkoasua halutaan muuttaa tai halutaan kokonaan uudentyyppisiä tulosteita (pdf, cvs) Nämä ovat eri vastuita ja ne pitäisi erottaa omiin luokkiinsa 12.9.2017 581358 Ohjelmistoarkkitehtuurit 15
Coupling Kytkentä (coupling) on ohjelmiston osien välisen assosiaation voimakkuuden mittari Voimakas kytkentä tekee erilliset osat vaikeammin ymmärrettäväksi, muutettavaksi ja korjattaviksi toisistaan riippumatta Esimerkiksi jos moduulin A luokka A.A pääsee suoraan käsiksi moduulin B luokan B.B toteutukseen (sen kenttiin), syntyy hyvin voimakas kytkentä, koska B.B:n toteutukseen tehtävä muutos todennäköisesti heijastuu välittömästi muutostarpeena A.A:n koodin, joka käsittelee suoraan B.B:n kenttiä Mittarille on tekninen määritelm(i)ä, mutta asian ydin on miettiä, millaisia heijastusvaikutuksia jonkin moduulin sisäisillä muutoksilla on muihin moduuleihin ja pyrkiä minimoimaan ne https://en.wikipedia.org/wiki/coupling_%28computer_programming%29 12.9.2017 581358 Ohjelmistoarkkitehtuurit 16
Ominaisuuksien ortogonaalisuus Suoralla y = a voi x:n valita vapaasti Jos x:n valinta ei vaikuta y:n arvoon ja päinvastoin, niin ominaisuudet (x ja y) ovat toisistaan riippumattomia Suunnittelussa ja arkkitehtuurissa: Moduulien / komponenttien välisen keskinäisen riippumattomuuden mitta https://en.wikipedia.org/wiki/orthogonality#computer_science 12.9.2017 581358 Ohjelmistoarkkitehtuurit 17 Y (0,a) (b,0) x=b y = a X
Cohesion Rakenneosan sisältämien elementtien yhteenkuuluvuuden (cohesion) mittari Yhteenkuuluvuuden eri asteita Toiminnallinen (hyvä!): kaikki rakenneosan elementit toimivat yhdessä jonkin tietyn, rajallisen tehtävän toteuttamiseksi (well-bounded behavior) Sattumanvarainen (huono!): osa on satunnainen kokoelma yhteenkuulumattomia abstraktioita ja toimintoja Asteita on muitakin, mutta oleellista on miettiä, (1) mikä on osan päätehtävä ja (2) miten sen elementit liittyvät tuon tehtävän suorittamiseen Voiko jotkut elementit siirtää pois päätehtävän kärsimättä? https://en.wikipedia.org/wiki/cohesion_%28computer_science%29 12.9.2017 581358 Ohjelmistoarkkitehtuurit 18
JÄRJESTELMÄN JAKAMINEN OSIIN 12.9.2017 581358 Ohjelmistoarkkitehtuurit 19
By NASA (Stardust Launch Press Kit [1]) [Public domain], via Wikimedia Commons https://commons.wikimedia.org/wiki/file%3astardust_-_launch_vehicle_assembly_diagram.png 12.9.2017 581358 Ohjelmistoarkkitehtuurit 20
"Legpuzzel" by Piero from nl. Licensed under CC BY-SA 3.0 via Wikimedia Commons https://commons.wikimedia.org/wiki/file:legpuzzel.jpg#/media/file:legpuzzel.jpg 12.9.2017 581358 Ohjelmistoarkkitehtuurit 21
Kokonaisuus koostuu osista Yleiset suunnitteluperiaatteet auttavat arvioimaan osituksen onnistumista (laatua), mutta eivät kerro, miten ositus käytännössä löydetään Oletusarkkitehtuuri (esim. ohjelmistokehys, framework) antaa valmiin kaavan, joka jakaa rakennettavan järjestelmän loogisesti ja fyysisesti erillisiin, tietyn rajatun tehtävän tai tarkoituksen täyttäviin rakenneosiin (moduulit, komponentit jne.) Arkkitehtuurityylit ja patternit tarjoavat suoraan lähtökohtia järjestelmän suunnittelulle ja ositukselle Mitä muita yleisiä tapoja on osittaa järjestelmä ja sen arkkitehtuuri? 12.9.2017 581358 Ohjelmistoarkkitehtuurit 22
Ositusstrategiat Kurssikirja esittelee joukon ositustapoja luvussa 11.3. Jotkut niistä ovat hieman abstrakteja Jako toiminnallisuuden mukaan on yleinen tapa Tarkastellaan, mitä kaikkea järjestelmän pitää tehdä (toiminnallisuus) Määritellään perusjako (yleensä jonkinlainen hierarkia), jossa toiminnallisuudet jaotellaan joko teknisen luonteen tai toiminnan tarkoituksen (sovellusalueen prosessien) perusteella Yhteenkuuluva toiminnallisuus yhteen elementtiin tai samalla hierarkian tasolla läheisessä yhteistoiminnassa oleviin elementteihin Myöhemmin kurssilla käsitellään R. C. Martinin Clean Architecture, joka esittelee erään perusosituksen mallin 12.9.2017 581358 Ohjelmistoarkkitehtuurit 23
Component Cohesion Millä perusteella yksittäiset luokat pitäisi koota moduuleiksi ja edelleen komponenteiksi (eli valmiiksi sellaisenaan käyttöön otettaviksi rakennuspalikoiksi)? REP (Release Equivalence Principle): samaan komponenttiin kootut elementit ovat sellaisia, että ne on järkeä julkaista yhtenä yksikkönä CCP (Common Closure Principle): kokoa samaan komponenttiin samasta syystä ja samaan aikaan muuttuvat elementit (= SRP komponenteille) CRP (Common Reuse Principle): komponentin elementtien (luokkien) pitäisi olla sellaisia, että niitä välttämättä tarvitaan aina yhdessä - eli komponentin käyttäjää ei saa pakottaa riippuvaiseksi elementeistä, joita se ei tarvitse Huom REP ja CCP kertovat, mitä komponenttiin kannattaa ottaa mukaan, mutta CRP kertoo, mitä kannattaa jättää pois 12.9.2017 581358 Ohjelmistoarkkitehtuurit 24
Component Coupling Komponenttien väliset lähdekoodiriippuvuudet eivät saa olla syklisiä Riippuvuuksien muodostama suunnattu verkko ei saa sisältää syklejä (mistään verkon solmusta ei pääsee takaisin siihen itseensä kaaria pitkin kulkien) Komponenttien muodostama rakenne ja siihen kuuluvat staattiset (koodi-) riippuvuudet ovat tärkeitä ohjelmiston ylläpidettävyydelle ja koostettavuudelle (buildability), joiden pitäisi ohjata rakenteen kehitystä Herkästi muuttuvat epävakaat (volatile) komponentit voivat riippua vakaiksi tarkoitetuista (harvoin ja vaikeasti muutettavista) komponenteista mutta ei päinvastoin: riippuvuus vakaaseen komponenttiin ei lisää herkän komponentin epävakautta, mutta riippuvuus epävakaaseen komponenttiin heikentää vakaan komponentin vakautta Hankalasti muutettavat komponentit eivät saa riippua herkistä epävakaista komponenteista myöskään siksi, että herkkyys katoaa: hankalasti muutettavaa komponenttia ei yleensä haluta muuttaa, joten herkkääkään komponenttia ei voida enää muuttaa (ainakaan riippuvuuksien osalta) 12.9.2017 581358 Ohjelmistoarkkitehtuurit 25
Dependency Inversion SOLID-periaate Dependency Inversion liittyy edelliseen Korkean tason moduulit ('business-logiikka') eivät saa riippua matalan tason moduuleista (tietokanta-ajurit) Molempien tulisi riippua abstraktioista, jotka määrittävät korkean tason moduulille näkymän alemman tason palveluihin (piilottaen niiden toteutuksen) Abstraktioiden ei pitäisi riippua detaljeista; detaljien pitäisi riippua abstraktioista 12.9.2017 581358 Ohjelmistoarkkitehtuurit 26
ARKITEHTUURITYYLIT JA - PATTERNIT 12.9.2017 581358 Ohjelmistoarkkitehtuurit 27
Arkkitehtuurityyli Architectural style Nimetty kokoelma tiettyyn käyttöyhteyteen soveltuvia yleisiä suunnitteluperiaatteita ja sääntöjä, jotka tuovat mukanaan hyödyllisiä ominaisuuksia rakennettavaan järjestelmään Esim. asiakas palvelin tyyli (Client-Server): Erottele palvelua pyytävä ja palvelun tarjoava ohjelmistokomponentti Piilota palvelua pyytävien komponenttien identiteetti palvelun tarjoajalta ja mahdollista useiden pyytäjien mahdollisesti vaihtelevan joukon palveleminen Eristä pyytäjät toisistaan Mahdollista useita palvelun tarjoajia; ja mahdollista tarjoajien määrän dynaaminen (käytön aikainen) lisääminen asiakkaiden määrän vaihtelun mukaan Ei ota kantaa käytettäviin kommunikaatiomekanismeihin (tietoliikenneprotokolla) 12.9.2017 581358 Ohjelmistoarkkitehtuurit 28
Arkkitehtuuripatterni (tai malli) Architectural pattern Nimetty kokoelma johonkin toistuvaan suunnitteluongelmaan soveltuvia suunnitteluratkaisuja, jotka on parametrisoitu ottamaan huomioon käyttöyhteys, jossa ongelma esiintyy Miten tyyli eroaa patternista? Tyylin käyttötilanne on yleisempi, patternin spesifimpi Tyylit ovat enemmän periaatesääntöjä ja patternit konkreettisia ratkaisuja Patternit soveltavat tyyliä (tyylejä) Patterniin voidaan yhdistää tyylejä. Tietty tyyliä noudattava ratkaisu voi sisältää useita patterneja. Huom - Kaikki lähteet eivät erottele näitä käsitteitä! 12.9.2017 581358 Ohjelmistoarkkitehtuurit 29
Kolmitasoarkkitehtuuri Käli-elementin sisältö Service requests Olio Data requests Tietokantataulun rivi Display (Presentation) business' logic Persistent state (Datastore) Values to display data values Käyttäjän näkymä J:n dataan ja toimintoihin -datan katselu -datan muokkaus Operaatiot, joita käyttäjä haluaa järjestelmän tekevän datan perusteella (liiketoimintaprosessit ja entiteetit) Datan pysyvä talletus ja jakaminen eri sovellusten kesken 12.9.2017 581358 Ohjelmistoarkkitehtuurit 30
Kolmitasoarkkitehtuuri -patterni Asiakaskone Tilauskäyttöliittymä Asiakaskone Tilauskäyttöliittymä Asiakaskerros reply request Asiakas palvelin tyyli Web- ja sovelluspalvelin Web-palvelin Sovelluspalvelin Sovelluskerros Tilausjärjestelmä request reply Tietokantapalvelin Tilaustietokanta Datakerros 12.9.2017 581358 Ohjelmistoarkkitehtuurit 31
Tyylien käytöstä Muitten jäljittely ja suunnittelun uudelleenkäyttö on hyvä oppimismenetelmä Kun käyttää tyylejä ja patterneja, on kuitenkin syytä ymmärtää miksi ja missä tilanteissa ne toimivat ja verrata tätä omaan käsillä olevaan suunnitteluongelmaan Joukko tyylejä ja patterneja käydään läpi seuraavilla luennoilla 12.9.2017 581358 Ohjelmistoarkkitehtuurit 32
Miten yleiset suunnitteluperiaatteet ilmenevät tässä arkkitehtuurissa? Asiakaskone Tilauskäyttöliittymä Asiakaskone Tilauskäyttöliittymä Asiakaskerros Web- ja sovelluspalvelin Web-palvelin Sovelluspalvelin Sovelluskerros Tilausjärjestelmä Tietokantapalvelin Tilaustietokanta Datakerros 12.9.2017 581358 Ohjelmistoarkkitehtuurit 33