Transcript Blue Border
Komponenttipohjainen ohjelmistotekniikka (TJTSS56) Osa 11 Kevätlukukausi 2010 Jyväskylän yliopisto Tietojenkäsittelytieteiden laitos Markku Sakkinen Ohjelmoinnin vivahteita Szyperski, luku 10 Joskus ajatellaan, että komponenttiohjelmistoja rakennettaessa ohjelmoinnin tarve vähenee radikaalisti. • Vain itse komponenttien tuottajat ohjelmoivat, muut vain kokoavat valmiita komponentteja sopiviksi kokonaisuuksiksi. • Jos tämä pitäisi paikkansa, suurin osa kirjasta (ja tästä kurssista) olisi turhaa. • ”Ohjelmointi on toiminnallisuuden lisäämistä tai muuttamista yhdistelemällä olemassa olevia ja uusia abstrakteja olioita jonkin ohjelmointimallin mukaisesti.” • Ohjelmointia tapahtuu jossakin muodossa järjestelmän kaikilla tasoilla, alkaen ohjelmoitavista mikropiireistä. • Vaikka ylimmillä tasoilla käytettäisiin skriptausta tai visuaalista komponenttien yhdistelyä, älylliset vaatimukset ovat suurimmaksi osaksi samat kuin ”tavallisessa” ohjelmoinnissa. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 13. 4. 2010 2 Ohjelmoinnin vivahteita (jatkoa) Vaatimusten käsittely (requirements engineering) • Ohjelmointimalli käsittelee kohdealueen olioita, niiden välisiä suhteita ja ajassa tapahtuvia muutoksia. • Suoritettavat vaatimusmäärittelyt ovat suositeltavia, varsinkin kriittisille järjestelmille. • Suoritettavan spesifikaation suorituskyvyllä ja resurssitarpeilla ei ole merkitystä – oleellinen ero varsinaiseen ohjelmistoon. Asiankäsittely (työnkulku) (work flow [engineering]) • Liiketoimintaprosessien sekä niihin kuuluvien tehtävien, työkohteiden (dokumenttien) ja resurssien kuvaaminen ja hallinta. • Laajimmillaan voi käsittää kokonaisen yrityksen toiminnan. • Järjestelmä voi olla automaattinen tai puoliautomaattinen. • Ohjelmoidaan myös ihmisten tehtäviä tai ainakin niiden yhteyksiä koneellisiin työvaiheisiin. • Työnkulun hallinta on tärkeää myös web-palveluissa. • Tähän on kehitetty omia kieliä, mm. WSFL (IBM) ja XLANG (Microsoft). Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 14. 4. 2010 3 Ohjelmoinnin vivahteita (jatkoa) Visuaalinen sovellusten rakentaminen • Kytketään valmiita komponentteja toisiinsa graafisella suorakäyttöliittymällä. • Yleensä samaan sovellukseen yhdistettävien komponenttien määrä on melko pieni ja niiden väliset riippuvuudet yksinkertaisia. • Suorituskyvyn ja resurssitarpeiden oletetaan riippuvan komponenteista, ei merkittävästi niiden välisestä ”johdotuksesta” (wiring). Juontaminen (skriptaus) (scripting) • Mahdollistaa useiden ohjelmien toiminnan monipuolisen yhdistämisen. • Vanhoissa eräkäsittelyyn (batch processing) perustuvissa käyttöjärjestelmissä oli ainakin jo 1960-luvulla hyvin monipuolisia työnohjauskieliä (job control language, JCL). • Osituskäyttö- ja muissa interaktiivisissa järjestelmissä puhutaan yleensä komentokielistä (command language). • Samaa kieltä käytetään yleensä sekä välittömään komentamiseen että skriptien kirjoittamiseen. • Putkien käyttö Unixin komentokielissä on melko yksinkertaista ohjelmien yhteenkytkemistä tietovirtojen kautta. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 14. 4. 2010 4 Ohjelmoinnin vivahteita (jatkoa) Juontokielet (scripting language) ovat ohjelmointikielten ja komentokielten välimuotoja (sumea käsite). • Useimpiin on viimeistään kehityksen myötä tullut täyden ohjelmointikielen mahdollisuudet (esim. Javascript, Python). • Ohjelmiston peruskomponentit oletetaan kuitenkin normaalisti kirjoitettavan ”varsinaisilla” ohjelmointikielillä. • Juontokielet ovat luonteeltaan tulkittavia, eikä niiden toteutuksissa ole yleensä pidetty suorituskykyä hyvin tärkeänä. Visuaaliset ja konkreetit menetelmät ja välineet ovat joissakin tilanteissa hyviä, mutta niillä on rajoitteensa. • ”Yksi kuva kertoo enemmän kuin tuhat sanaa.” • Kristen Nygaardin vastaesimerkki (ECOOP ’92): piirtäkää kuva, joka näyttää, mikä kulkuneuvo on. • Abstraktioita tarvitaan, ja niiden täsmälliseen määrittelyyn tarvitaan symboleita, tavallisimmin tekstiesitystä. • Graafiset esityksetkin voivat olla täysin abstrakteja ja symbolisia, esim. luokkakaaviot. • Ne eivät sovellu hyvin formaaliin päättelyyn eivätkä automaattiseen käsittelyyn. • Esim. elektronisten komponenttien suunnittelussa on paljolti siirrytty graafisista kaavioista formaaleihin kieliin. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 14. 4. 2010 5 Yhteyspohjainen (connection-oriented) ohjelmointi Voidaan sanoa, että tavanomainen ohjelmointi noudattaa kysyntämallia (pull model): asiakas A kutsuu palvelimen P operaatioita silloin, kun se tarvitsee niitä. Joissakin tapauksissa tarvitaan tarjontamallia (push model): komponentti B ilmoittaa komponentille A tapahtumista, joihin B:n pitää reagoida. • Tieto kulkee siis päinvastaiseen suuntaan kuin tavallisesti. • Ilmoittaminen voi tapahtua takaisinkutsulla (ks. lukua 5). • Tällaista tapahtuu MVC-mallissa (tai –kehyksessä) ja Observer-suunnittelumallissa. • MVC:ssä näkymä (sen takaisinkutsuttavat operaatiot) vieläpä kutsuu puolestaan joitakin mallin operaatioita. Perinteisesti ja yksinkertaisimmillaan kysyntämallissa asiakas tietää staattisesti, mitä operaatiota se kutsuu. • Tähän voidaan kuitenkin lisätä myöhäistä sidontaa ja epäsuoruustasoja. • Silloin voidaan sanoa, että kutsujan ja kutsuttavan välillä on yhteys, ”johdotus”. • Useissa proseduraalisissa kielissä (esim. Pascalissa ja C:ssä) on yhtenä muuttujantyyppien lajina aliohjelmanosoite. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 6 Yhteyspohjainen ohjelmointi (jatkoa) • Oliokielten normaalissa metodinkutsussa tapahtuu jo myöhäinen sidonta, ja lisää epäsuoruustasoja saadaan kutsujen edelleenlähettämisellä. Tarjontamallissa ilmoittava komponentti ei useimmiten tiedä staattisesti ilmoituksen vastaanottajia. • Käytetään yleensä epäsuoraa yhteyttä. • Toteutustasolla kysyntä- ja tarjontamallin yhteyksiä käsitellään samalla tavoin. Yhteyspohjaisessa ohjelmoinnissa korvataan staattiset kutsuriippuvuudet epäsuorilla yhteyksillä, joita voidaan määritellä ja muuttaa ajon aikana. • Yhä useammin yhteysmekanismit erotetaan omiksi palveluikseen, esim. viesti- ja tapahtumapalveluiksi. • Tässä ”tapahtuma” tarkoittaa samaa kuin event, ei transaction. • Väliohjelmisto voidaan jopa rakentaa kokonaan viestien ja viestinjakelun pohjalle: message-oriented middleware (MOM). • Oliokeskeisissä väliohjelmistoissa (EJB, COM+, CORBA, .NET) viesti- ja tapahtumapalvelut ovat keskenään yhtä tärkeitä. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 7 Yhteyspohjainen ohjelmointi (jatkoa) • Oliokielten normaalissa metodinkutsussa tapahtuu jo myöhäinen sidonta, ja lisää epäsuoruustasoja saadaan kutsujen edelleenlähettämisellä. Tarjontamallissa ilmoittava komponentti ei useimmiten tiedä staattisesti ilmoituksen vastaanottajia. • Käytetään yleensä epäsuoraa yhteyttä. • Toteutustasolla kysyntä- ja tarjontamallin yhteyksiä käsitellään samalla tavoin. Yhteyspohjainen ohjelmointi on tärkeää silloin, kun valmiita komponentteja tai niiden tuottamia olioita ”langoitetaan” yhteen. • Tässä asiassa elektroniikan integroidut piirit (IC:t) ovat hyödyllinen analogia. • Piirissä on useita jalkoja, joista osa on tuloja (syötteitä) ja osa lähtöjä. • Piirin dokumentointi selittää tarkasti jokaisen tulo- ja lähtösignaalin ja sen merkityksen. • Perinteisessä ohjelmoinnissa on keskitytty ”tulosignaaleihin”. • Yhteyspohjainen ohjelmointi käsittelee tulevia ja lähteviä liitospisteitä (portteja) yhtäläisesti. • Puhutaan tarjotuista eli tulevista sekä vaadituista että lähtevistä rajapinnoista. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 8 Yhteyspohjainen ohjelmointi (jatkoa) • Tarjottu rajapinta vastaa perinteistä, aliohjelmista tai metodeista koostuvaa rajapintaa (siis integroidun piirin tulojalkoja). On huomattava, että tulevien ja lähtevien rajapintojen ero tarkoittaa kutsun eikä tietovirran suuntaa. • Erityisesti perinteisestä aliohjelman kutsusta voidaan palauttaa tietoa (paluuarvo ja monissa kielissä myös tulosparametrejä) kutsujalle. • Rajapinta yksinään ei ole tuleva eikä lähtevä (kuten on jo usein korostettu). • Komponentin lähtevien rajapintojen määrittely tarkoittaa niiden kutsujen, viestien ja tapahtumien määrittelyä, joita komponentti voi lähettää. Perinteinen ohjelmointimalli on epäsymmetrinen. • Kutsujalla täytyy olla suora tai epäsuora viite kutsuttavaan, mutta kutsuttava ei tiedä mitään kutsujistaan. • Tarvittaessa kutsussa on jollakin parametrillä ilmoitettava kutsuvan olion tai metodin osoite. • Tämä on kokonaan ohjelmoijan vastuulla – tarkoituksella tai vahingossa todellisena parametrinä voidaan antaa jonkin muun olion tai metodin osoite. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 9 Yhteyspohjainen ohjelmointi (jatkoa) Perinteinen ohjelmointimalli on epäsymmetrinen. • Yhteyspohjaisessa ohjelmoinnissa yhdistetään komponentin tai olion kukin lähtevä rajapinta jonkin toisen komponentin tai olion yhteensopivaan tulevaan rajapintaan. • Joko dynaamisesti ajon aikana tai jossakin varhaisemmassa vaiheessa. • Vahvasti tyypitetyissä järjestelmissä yhdistäminen on mahdollista vain, jos tulevan rajapinnan tyyppi on sama kuin lähtevän rajapinnan tyyppi tai tämän alityyppi. Yhteydet sinänsä ovat riippumattomia komponenttien tuonneista (imports) ja vienneistä (exports) sekä järjestelmän kerroksista. • Jossakin komponenttikehyksessä voi esim. olla yhteinen kerros, jossa määritellään lukuisia rajapintoja. • Kehykseen liitettävä komponentti tuo tämän yhteisen kerroksen ja määrittelee, mitä sen rajapintoja se käyttää tulevina, lähtevinä tai molempina. • Useat riippumattomasti kehitetyt komponentit voivat tuottaa olioita, jotka voidaan yhdistää toisiinsa näiden rajapintojen kautta. • Luodut yhteydet voivat olla joko samassa kerroksessa kuin nuo komponentit tai ylemmässä kerroksessa, jossa yhteydet luodaan. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 10 Yhteyspohjainen ohjelmointi (jatkoa) Tällaisen erillisen yhteyskerroksen tarvitsee ehkä pitää huolta yhteyksien säilyvyydestä (persistence). • Se voi olla tärkeää, jos itse oliotkin ovat säilyviä. Yksi tapa, jolla olioiden luonti ja yhdistäminen voidaan määritellä yhdessä, on koosteluokan ja siis koosteolioiden käyttö. • Olkoon olemassa luokka L1, jolla on tuleva rajapinta A ja lähtevä rajapinta U, sekä luokka L2, jolla on tulevat rajapinnat B ja U ja lähtevä rajapinta V. • Näiden avulla voidaan määritellä koosteluokka K, jolla on tulevat rajapinnat A ja B sekä lähtevä rajapinta V. • Kun jokin K:n olio luodaan, se luo L1:n olion o1 ja L2:n olion o2, yhdistää ne toisiinsa U:n kautta, kytkee o1:n A-rajapinnan ja o2:n B-rajapinnan omiin tuleviin rajapintaansa sekä o2:n V-rajapinnan omaan lähtevään rajapintaansa. Yhteyspohjainen ohjelmointi on yksi erityisesti komponenttipohjaisiin järjestelmiin sopiva ohjelmointityyli, mutta muitakin on: • Ns. atribuuttipohjainen ohjelmointi ja siihen liittyvä automaattinen kontekstuaalinen koostaminen. • Ns. datapohjainen koostaminen (data-driven composition): vastaanotetun viestin tyyppi ja sisältö määrä seuraavan toiminnon. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 11 Yhteyspohjainen ohjelmointi (jatkoa) Yhteyspohjaisen ohjelmoinnin erityisetu hajautetuissa järjestelmissä: hajautus jää yhteysabstraktion sisälle. • Komponenttien ja luokkien ei tarvitse ottaa siihen kantaa. Yhteyspohjaisuus ei vaadi eikä takaa komponenttipohjaisuutta. • Kytkettävien yksiköiden rakeisuus voi olla liian karkea tai liian hieno komponenteiksi. • Yhteydet eivät välttämättä perustu sopimuksellisesti määriteltyihin rajapintoihin. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 12 Yhteyspohjainen ohjelmointi – edistyneitä käsitteitä Kun yhteyksiä tarkastellaan omina olioinaan, voidaan ajatella monimutkaisempiakin verkkorakenteita, kuten muiden mallinnusalojen (esim. sähkö- ja vesijohtojen) yhteysverkoissa. • Sama kutsuja voidaan yhdistää useihin kutsuttaviin ja päin vastoin. • Voidaan määritellä kanavia eli yhteysryhmiä, jotka liittävät joukon kutsujia joukkoon kutsuttavia. • Sekä kutsujia että kutsuttuvia voidaan lisätä ryhmään tai poistaa siitä vaikuttamatta muihin osapuoliin. • Tällainen kanava on normaali olio, jolla on sama rajapinta (tai useita rajapintoja) sekä tulevana että lähtevänä. • Kanavan sopimukseen kuuluu, että se välittää saamansa kutsut ja tulokset edelleen. • Kanava voi tehdä muutakin, esim. suodattaa, viivästää tai kirjata (log) välittämiään viestejä. • Monesti olisi hyödyllistä määritellä kanava geneeriseksi. • Ei tarvitse toistaa samanlaista ohjelmointia eri rajapintoja varten. • Ääritapauksena kanava, joka vain välittää kaikki viestit sellaisinaan, toimii kaikille rajapinnoille samalla tavoin. Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 11 15. 4. 2010 13