Suunnittelumalli

Wikipedia
Loikkaa: valikkoon, hakuun

Suunnittelumalli (engl. Design Pattern) on ohjelmistotekniikassa ohjelmistorakenteen käsitteelliset (abstraktit) avainkohdat määrittävä kuvaus toistensa kanssa yhteistoiminnassa olevista luokista ja olioista. Suunnittelumalli sisältää yleisellä tasolla esitetyn ratkaisun johonkin oliopohjaisen suunnittelussa esiintyvään tavanomaiseen tilanteeseen tai kohteeseen.[1] Suunnittelumalli perustuu käytännön kokemukseen ratkaisun toimivuudesta tietyssä tilanteessa, ja sen käytöstä on pitkä kokemus. Suunnittelumallin tärkeimmät osat ovat ongelma, ongelmayhteys ja ratkaisu.[2] Suunnittelumallia voidaan käyttää työvälineenä suunniteltaessa ohjelman konkreettista arkkitehtuuria[3].

Yleistä[muokkaa | muokkaa wikitekstiä]

Suunnittelumalli on yleiskäyttöinen, käytännössä toimiva, uudelleenkäytettävä ja oliosuuntautunut ohjelmointilähtökohta, jota aloitteleva ohjelmoija ei tunne[4]. Suunnittelumalli voi myös koskea ohjelman suppeaa yksityiskohtaa[5]. Suunnittelumallin määrittelyssä kerrotaan sen käyttökohde, käyttöä rajoittavat tekijät, mallin seuraukset ja sen vahvuudet ja heikkoudet. Suunnittelumallin käyttö edellyttää riittävät ominaisuudet omaavan oliokielen käyttöä (esim. C++).[6] Paras keino ymmärtää ja omaksua suunnittelumalli on sen tutkiminen[7].

Suunnittelumallissa ei ole tärkeintä malli itse, vaan se suunnittelukokemus ja asiantuntemus, joka sitä käyttäen saadaan säilytettyä ja siirrettyä muille ohjelmoijille. Kerätty informaatio tulee esittää käytännönläheisessä, selkeässä ja järjestelmällisessä muodossa, jolloin malli antaa käytännön ohjelmointityöhön järjestetyn ja valmiin kokoelman tiettyihin tilanteisiin sopivia ratkaisuja. Suunnittelumalleja ei tule käyttää tilanteissa, joista niistä ei ole hyötyä.[8]

Ohjelmistoarkkitehtuurin kannalta suunnittelumallit käsittelevät yleensä suhteellisen pieniä yksiköitä (mikroarkkitehtuuria), mutta suunnittelumalleja voidaan käyttää myös koko sovelluksen perusrakenteessa (makroarkkitehtuuri). Suunnittelumallien ideaa on sovellettu käänteisenä keräämällä ns. antisuunnittelumalleja, joissa esitetään virheellisiä suunnitteluratkaisuja. Antisuunnittelumallia voidaan käyttää tunnistamaan ohjelmarakenteen virheitä ja suositeltavan suunnittelumallin soveltamiseen virheen poistamiseksi.[9]

Historia[muokkaa | muokkaa wikitekstiä]

Suunnittelumallin käyttö ohjelmistotekniikassa perustuu amerikkalaisen arkkitehdin Christopher Alexanderin esittämään ajatukseen (Alexander, C. & ym. (1977). A Pattern Language. New York: Oxford University Press[10]) siitä, että rakentaminen perustuu hyväksi havaittujen ratkaisumallien keräämiseen, oppimiseen ja toistamiseen. Eräät ohjelmistotekniikan tutkijat (Kent Beck, Jim Coplien, Erich Gamma, ym.) tutustuivat näihin ajatuksiin, ja ryhtyivät kehittämään niiden käyttöä ohjelmointitekniikan yhteydessä.[11]

Vuoden 1994 elokuussa pidetty PLoP-konferenssin (Pattern Language of Programming) jälkeen aloitettiin useita projekteja suunnittelumallien löytämiseksi. Vuoden 1995 alussa Erich Gamma, Richard Helm, Ralph Johnson ja John Vlissides ("Gang of Four") julkaisivat Design Patterns: Elements of Reusable Object-Oriented Software, jossa esitettiin 23 suunnittelumallia.[12]

Aikaisemmin Kent Beck ja Ward Cunningham toivat suunnittelumallit ohjelmistosuunnitteluun vuoden 1987 OOPSLA-konferenssissa. Vaikka he käyttivätkin esittelemiään suunnittelumalleja olio-ohjelmoinnin suunnittelussa, eivät ne olleet oliosuunnittelumalleja sanan nykyisessä merkityksessä, vaan niitä voidaan pitää käytettävyysmalleina. Erich Gamma oli käsitellyt suunnittelumalleja vuonna 1991 julkaistussa väitöskirjassaan, ja häntä pidetään suunnittelumallien tärkeimpänä kehittäjänä.

Suunnittelumallin sisältö[muokkaa | muokkaa wikitekstiä]

Suunnittelumallia kuvataan yleensä sen perustiedoilla, jotka määrittelevät mallin ja kuvaavat sen toiminnan.Nämä perustiedot ovat nimi, ongelman kuvaus, ratkaisun kuvaus ja ratkaisun vaikutukset ohjelmistoon ja tietokoneen laitteisiin. Muita suunnittelumallista esitettäviä tietoja voivat olla mm. luokittelu, mallista käytettävät muut nimet, esimerkki käyttötilanteesta, soveltuvuus, rakenteen esittäminen kaaviolla, malliin kuuluvat luokat ja niiden välinen tehtävien jako (vastuut), luokkien väliset rajapinnat, toteutuksessa esiintyvät ongelmat (esim. ohjelmointikielen vaikutus), esimerkki mallin toteuttamisella ohjelmointikielellä, esimerkkejä käytöstä todellisissa ohjelmissa ja mallia muistuttavat muut mallit ja mallit, joiden kanssa mallia olisi hyvä käyttää.[13]

Nimi[muokkaa | muokkaa wikitekstiä]

Suunnittelumallin nimi kuvaa mallin sisältämän periaatteen lyhyesti ja yksiselitteisesti. Mallin nimen perusteella voidaan nopeasti hahmottaa käytetty rakenne, sen tuottama hyöty ja siihen liittyvät rajoitukset. Mallin nimi auttaa ohjelmiston suunnittelemaan ajattelemaan ohjelmistorakennetta yleisellä (abstraktilla) tasolla, ja sen käyttö voi helpottaa suunnittelijoiden välistä keskustelua.[14] Suunnittelumallin nimen tulisi olla osa suunnittelijan ammattisanastoa, mutta tilannetta on vaikeuttanut mm. se, että sama suunnittelumalli on nimetty eri nimillä tai käytännössä samat suunnittelumallit on nimetty eri nimillä. Samaa nimeä voidaan myös käyttää eri suunnittelumalleille.[15]

Ongelma[muokkaa | muokkaa wikitekstiä]

Ongelma (Problem) kuvaa ohjelmoinnissa esiintyvää tavanomaista tilannetta, jonka ratkaisemisessa suunnittelumalli on ollut hyödyksi. Ongelman kuvaus voi olla laaja arkkitehtuuriin liittyvä tai sitten suppeampi, esim. tietyn algoritmin kuvaus. Suunnittelumalli voi joskus sisältää ominaisuuksia, joiden vuoksi sitä ei ole tarkoituksenmukaista käyttää muissa kuin erityistilanteissa. Nämä erityistilanteet on kuvattu tässä osassa suunnittelumallin määrittelyä.[16] Ongelman tulee ilmetä toistuvasti monenlaisissa ohjelmistoissa ja sen tulee olla yleisluontoinen (esim. ohjelmointikielestä riippumaton). Muut kuin arkkitehtuuri- tai yksityiskohtaiseen suunnitteluun liittyvät ongelmat rajataan pois.[17]

Ongelma esittää tilanteen, jossa mallia voidaan soveltaa. Ongelman kuvaus esitetään tarkasti identifioituna, mikä helpottaa käyttöalueen määritystä. Kuvaus voi myös esittää jonkin tyypillisen joustamattoman rakenteen, jota on parannettava. Suunnittelumallia ei ole syytä käyttää ellei ongelman kuvaus vastaa toteutettavassa ohjelmistossa esiintyvää ongelmatilannetta. Yleisesti voidaan todeta, että suunnittelumallien tehokas soveltaminen vaatii huolellista pohdintaa, sillä mallien soveltaminen voidaan tehdä vain suppeasti määritellyllä ongelma-alueella. Joskus ongelman kuvaus sisältääkin listan ehdoista joiden tulee täyttyä ennen kuin on hyödyllistä soveltaa suunnittelumallia.

Ongelmayhteys[muokkaa | muokkaa wikitekstiä]

Ongelmayhteys (Context) kuvaa sen kokonaisuuden, jossa ongelma ilmenee, ja se kertoo sen, missä tilanteissa suunnittelumallia voidaan käyttää. Ongelmayhteys määrittää lisäksi ratkaisulle asetettavia vaatimuksia ja niitä ohjelman laatuominaisuuksia, joita ratkaisun tulisi parantaa. Usein ongelma ja ongelmayhteys esitetään yhdessä, ja niitä havainnollistetaan esimerkeillä.[18]

Ratkaisu[muokkaa | muokkaa wikitekstiä]

Ratkaisu (Solution) kuvaa mahdollisen ohjelmointirakenteen ja sen osat (esim. luokat, oliot, algoritmit), osien väliset suhteet ja niiden välisen vuorovaikutuksen (yleensä funktiokutsut) yleisellä tasolla. Ratkaisun antamia ohjelmoinnin suuntaviivoja on käytettävä käsitteellisenä runkona laadittaessa käytännön ratkaisua käsillä olevaan ohjelmointiongelmaan. Ohjelmistosuunnittelija arvioi tapauskohtaisesti sen, miten mallin ratkaisu sopii kyseessä olevaan tilanteeseen.[19] Ratkaisun tulee olla sovellettavissa yleisesti ohjelmoinnissa, ja se tulee pystyä esittämään yleisti käytössä olevalla mallinnuskielellä (esim. UML). Ratkaisun yleiskäyttöisyydestä voi seurata se, että ohjelmiston laatuominaisuudet (esim. nopeus) heikkenee.[20]

Ratkaisu on suunnittelumallin tärkein asia, ja se esitetään usein staattisena rakenteena (esim. UML:n luokkakaavio) jota täydennetään dynaamisen vuorovaikutuksen kaaviolla (esim. UML:n sekvenssikaavio). Kuvausta voidaan täydentää pseudokoodikuvauksella, joka kuvaa ohjelman kulun vaihe vaiheelta.[21]

Ratkaisun tehtävänä on muodostaa yleinen kuvaus ongelman ratkaisusta. Ratkaisu kuvaa toteutuksessa käytettävät luokat, rajapinnat ja oliot, sekä niiden suhteet yleisellä tasolla. Vaikka ratkaisun rakenne esitetään yleensä UML-kaaviolla tai jollain muulla oliorakennetta kuvaavalla yleisesti tunnetulla kuvaustavalla (notaatio), ei ratkaisu kuvaa mitään erityistä tilannetta vaan yleisen tavan ratkaisulle. Tosin yksinkertainen esimerkki helpottaa ratkaisun toteutustavan ymmärtämistä. Ratkaisussa ei yleensä oteta kantaa käytettävään ohjelmointikieleen, mutta esimerkiksi moniperinnän puuttuminen osasta oliokieliä saattaa hankaloittaa ratkaisun toteuttamista. Yleisesti suunnittelumalleissa ei käytetä jonkin tietyn kielen erityisominaisuuksia ongelman ratkaisuun.

Seuraukset[muokkaa | muokkaa wikitekstiä]

Seuraukset kuvaa mallin vaikutusta ohjelman sisäiseen ja ulkoiseen toimintaan, sekä sen käytöstä seuraavia hyviä ja huonoja seikkoja. Ohjelmistojen toiminnan kannalta tärkeitä seurauksia ovat mm. muisti ja suoritusaika ja ohjelmiston uudelleenkäyttö. Ohjelmiston uudelleenkäytön kannalta tärkeitä seurauksia ovat mm. käytetyn mallin vaikutus ohjelman laajennettavuuteen, muunneltavuuteen ja siirrettävyyteen.[22] Mikään suunnittelumalli ei tuota joka suhteessa parasta ratkaisua, vaan kukin niistä optimoi tietyt ohjelman laatuominaisuudet ja heikentää muita. Seurausten kuvaaminen auttaa suunnittelijaa arvioimaan sitä, miten malli soveltuu käsillä olevaan suunnittelutilanteeseen. Seurauksista kertominen helpottaa suunnittelumallin soveltamista käytännön ohjelmistotyössä.[23]

Toteutusnäkökulma ja esimerkit[muokkaa | muokkaa wikitekstiä]

Toteutusnäkökulma kertoo käytännön ohjelmoinnissa esiintyvien tilanteiden ratkaisemisesta, esimerkiksi kertomalla mallin käytöstä eri ohjelmointikieliä käytettäessä. Toteutusnäkökulma on pidettävä erillään suunnittelumallin esittämästä teoreettisesta ajattelutavasta. Suunnittelumallin käytöstä voidaan antaa esimerkki todellisen järjestelmän toteutuksessa tai ohjelmointikielikohtaisena.[24]

Luokittelu[muokkaa | muokkaa wikitekstiä]

Suunnittelumallit luokitellaan yleensä sen tarkoituksen (luonti, rakenne, käyttäytyminen) ja sen kohteen (luokka, olio) perusteella. Mallit voidaan luokitella lisäksi myös sen mukaan, mitä malleja käytetään yleensä toistensa kanssa, mitkä mallit ovat toistensa vaihtoehtoja tai rakenteeltaan toisiaan vastaavia. Mallien luokittelun tarkoituksena on jäsentää ohjelmistoa käsitteellisiä lähestymistapoja (abstraktiotaso) kuvaavat mallit toistensa suhteen ja nopeuttaa mallien oppimista.[25]

Luontimallit[muokkaa | muokkaa wikitekstiä]

Luontimalli on suunnittelumalli, jolla ohjelmassa toimivan olion rakentaminen esitetään käsitteellisellä tasolla. Luontimalli peittää konkreettisesti käytettävien tuotantoluokkien näkyvyyden niitä käyttäviltä luokilta ja sen, miten tuotantoluokkia luodaan ja yhdistellään toisiinsa, eli tuotantoluokkia käyttävä tilaajaohjelma tuntee niistä vain niiden abstraktissa luokassa esitettävän rajapinnan. Rajapinnan käyttö mahdollistaa sen, että tuotantoluokkia ja niiden välisiä suhteita on helppo muuttaa ilman että sillä olisi vaikutusta luokkia tilaavan ohjelman toimintaan.[26] Luontimalli kuvaa olioiden luomisprosessin, eli sen, kuinka, koska ja mitä olioita luodaan, ja huolehtivat luokkien ja olioiden asetusten konfiguroinnista[27].

Luontimalli on suunnittelumalli, jossa monimutkainen toiminnallisuus toteutetaan yhdistämällä useita eri toiminnallisuuksia. Luontimallit kätkevät tiedon siitä, mitä luokkia toiminnallisuuden toteuttamisessa käytetään ja miten näitä luokkia käytetään, luodaan ja liitetään toisiinsa.[28]

Epäkonkreettinen tehdas[muokkaa | muokkaa wikitekstiä]

Epäkonkreettinen tehdas (Absract Factory, Kit) on olion luontimalli, jossa konkreettisten luokkien olioryhmä (-perhe) luodaan luokasta jolla itsellään ei ole konkreettista ilmentymää (abstrakti luokka). EKT on rajapintaluokka, joka yhdistää toisiinsa saman tyyppisiä oliota.[29]

EKT:tä voidaan käyttää ohjelman rakenteen mallina esim. käyttöliittymän toteutukseen eri alustoilla seuraavasti: Sovellusta käytetään eri käyttöliittymässä, jolloin käyttöliittymän rakentamistyökalun tulee tukea erilaisia käyttöliittymästandardeja. Käyttöliittymää luotaessa sovellus kutsuu abstraktin luokan (esim. UITehdas) funktiota (esim. luoIkkuna(), luoVierityspalkki(), luoPainonappi), joka edelleen kutsuu kyseisen ohjelmaympäristön konkreettista luokkaa, joka toteuttaa tarvittavat toiminnallisuudet. [30]

EKT toteutetaan usein tehdasmenetelmällä, ja toteutuksessa voidaan käyttää myös prototyyppimallia. Abstraktin tehtaan alaluokka konkreettinen tehdas on tavallisesti ainokainen (luokasta luodaan vain yksi ilmentymä).[31]

Rakentajarajapinta[muokkaa | muokkaa wikitekstiä]

Rakentajarajapinta (Builder) on olion luontimalli, jossa erotetaan toisistaan olion esitysmuoto ja sen luomisprosessi. Tämän vuoksi sama prosessi voi tuottaa erilaisia olioita. Absrakti rakentaja on abstrakti rajapintaluokka, joka luo konkreettisen rakentajaluokan osat. Rakentajaluokka toteuttaa halutut toiminnallisuudet (tuotteet).[32]

Rakentajaa voidaan käyttää ohjelman rakenteen mallina esim. muunnettaessa RTF-muotoista tekstiä muihin tekstiformaatteihin (esim. ASCII, muotoiltu teksti, jota ei voida muokata, muotoiltu teksti, jota voidaan muokata). RTFLukija (pääohjelma) kutsuu abstraktin rakentajan (TekstiKonvertoija), joka kutsuu edelleen konkreettisen rakentajan (ASCIIKonvertoija, TekstiKonvertoija, TekstiMuokkausKonvertoija) pääohjelman funktiokutsun sisältämän tiedon mukaan. Konkreettinen rakentaja määrittelee tuotteen kokoamisen prosessin ja kokoaa tuotteen sisäisen esitysmuodon.[33]

Rakentajarajapinta muistuttaa epäkonkreettista tehdasta siinä, että molemmilla voidaan toteuttaa monimutkaisia toiminnallisuuksia. Mallit eroavat toisistaan siinä, että epäkonkreettinen tehdas palauttaa pyydetyn tuotteen välittömästi, kun taas rakentajarajapinta valmistaa tuotteen vaiheittain ja palauttaa sen prosessin viimeisenä vaiheena. Rakentajarajapintaa käytetään usein rekursiokoosteen kokoamiseen.[34]

Tehdasfunktio[muokkaa | muokkaa wikitekstiä]

Tehdasfunktio (Factory Method, Virtual Constructor) on luokan luontimalli, jossa käytetään abstraktia funktiokutsua. Olion kutsumuoto on määritelty, ja luokan ilmentymän luominen on aliluokan tehtävä. Tehdasfunktiomallissa abstrakti luokka kapseloi konkreettisen luokan tarvitsemat tiedot ja välittää ne konkreettiselle tuotantoluokalle.[35] Tehdasfunktiota voidaan käyttää ohjelman rakenteen mallina esim. sovelluksessa, joka tuo käyttäjän muokattavaksi useita dokumentteja.[36]

Prototyyppirajapinta[muokkaa | muokkaa wikitekstiä]

Prototyyppirajapinta (Prototype) on olion luontimalli, jossa olion määrittely suoritetaan abstraktilla prototyyppiluokalla. Olio luodaan prototyyppiluokkaa kutsumalla ja luomalla siitä kopioita (kloonaus). Kopioiden ominaisuuksia voidaan muokata parametreilla, jolloin voidaan vähentää luokkien määrää.[37]

Ainokainen[muokkaa | muokkaa wikitekstiä]

Ainokainen (Singleton) on olion luontimalli, jossa luokasta luodaan täsmälleen yksi konkreettinen ilmentymä. Ilmentymään pääsy on globaali.[38] Ainokainen määritellään C++:ssa Instance()-funktiolla[39].

Rakennemallit[muokkaa | muokkaa wikitekstiä]

Rakennemalli on suunnittelumalli, joka kuvaa luokkia (ja olioita) ja niiden yhdistelyä suuremmiksi rakenteiksi[40]. Rakennemalli kuvaa tavan, jolla luokkia ja olioita käytetään laajoissa rakenteissa. Rakennemalli esittää rajapinnat ja toteutuksen toisistaan erotettuina.[41]

Sovitin[muokkaa | muokkaa wikitekstiä]

Sovitin (Adapter, Wrapper) on luokan tai olion rakennemalli, jossa kaksi toisiinsa sopimatonta rajapintaa liitetään toisiinsa käyttäen rajapintaluokkaa.[42]

Silta[muokkaa | muokkaa wikitekstiä]

Silta (Bridge, Handle, Body) on ohjelmiston rakennemalli, jossa sovellukseen liitetty abstrakti rajapintaluokka kutsuu haluamansa toiminnallisuuden abstraktilta toiminnallisuuden rajapintaluokalta. Nämä kaksi rajapintaa muodostavat sillan, ja molempia rajapintoja voidaan vapaasti muunnella.[43]

Koosteensa sisältävä kooste[muokkaa | muokkaa wikitekstiä]

Koosteensa sisältävä kooste (rekursiokooste, Composite) on ohjelmiston rakennemalli, jossa yksi koosteolion rakentava abstrakti luokka käsittelee kyseistä koostetta samalla tavalla ja samanaikaisesti konkreettisten aliluokkien olioiden kanssa. Ohjelma käsittelee kaikkia itsensä sisältävän koosteen osia samalla tavalla.[44]

Kuorruttaja[muokkaa | muokkaa wikitekstiä]

Kuorruttaja (Decorator, Wrapper) on suunnittelumalli, jossa oliolle (ei koko luokalle) lisätään toiminnallisuutta (vastuita) ajon aikana (dynaamisesti) käyttämällä abstraktia rajapintaluokkaa, jonka alaluokat toteuttavat toiminnallisuuden. Kuorruttaminen on joustava vaihtoehto perinnälle.[45]

Julkisivu[muokkaa | muokkaa wikitekstiä]

Julkisivu (Facade) on ohjelmiston rakennemalli, jossa julkisivu-luokka tarjoaa yhden yhtenäisen rajapinnan alijärjestelmäluokkien rajapintojen joukolle ja niiden keskeisille palveluille. Julkisivu vähentää alijärjestelmien riippuvuuksia ja niiden välistä kommunikaatiota ja helpottaa alijärjestelmän käyttöä.[46]

Hiutale[muokkaa | muokkaa wikitekstiä]

Hiutale (Flyweight) on ohjelmiston rakennemalli, jossa yhteiskäyttöistä oliota käytetään samanaikaisesti useissa eri yhteyksissä. Hiutale käyttäytyy jokaisessa käyttöyhteydessään itsenäisesti. Hiutaleessa olion sisäinen ja ulkoinen tila on erotettu toisistaan, sisäinen tila on tallentuneena hiutaleeseen, ja ulkoinen tila vaihtelee tilanteen mukaan ja riippuu asiayhteydestä.[47]

Edustaja[muokkaa | muokkaa wikitekstiä]

Edustaja (Proxy, Surrogate) on ohjelmiston rakennemalli, jossa olioille luodaan korvike (tai paikanpitäjä) käyttäen abstraktia rajapintaluokkaa, jonka alaluokka konkreettinen Edustaja-luokka on. Edustaja-luokka kontrolloi olioon kohdistuvia pyyntöjä.[48]

Käyttäytymismallit[muokkaa | muokkaa wikitekstiä]

Käyttäytymismalli kuvaa ohjelman kulun vaihe vaiheelta (algoritmi), olioiden tehtävät (vastuut) ja olioiden suhteet toisiinsa ja niiden välisen yhteistyön (vuorovaikutus). Käyttäytymismalli kuvaa lisäksi ohjelmiston staattisen rakenteen (luokat).[49] Käyttäytymismalli voi olla luokkiin perustuva (mm. operaatiorunko- ja tulkkimalli), olioihin perustuva (mm. tarkkailija-, vastuuketju- ja välittäjämalli) tai toiminnallisuuden kapselointi olioon (mm. iteraatio-, komento-, strategia-, tila- ja vierailijamalli).[50] Käyttäytymismalli kuvaa olioiden välisen ohjelman suorituksen aikana tapahtuvan dynaamisen vuorovaikutuksen[51]

Yleisfunktio[muokkaa | muokkaa wikitekstiä]

Yleisfunktio (Template Method) perustuu toimintojen delegointiin luokille perintää käyttäen. Abstraktissa rajapintaluokassa määritellään tuotantoluokkien ne toiminnallisuudet, jotka ovat samat kaikissa alaluokissa. Tuotantoluokissa määritellään ne toiminnallisuudet, joiden käyttäytyminen voi vaihdella.[52]

Tulkki[muokkaa | muokkaa wikitekstiä]

Tulkki (Interpreter) perustuu toimintojen delegointiin luokille perintää käyttäen. Laaditaan ohjelmointikieli, jolla voidaan määritellä haluttu toiminnallisuus. Ohjelmoidaan luokkia käyttäen tulkkausohjelma, joka kääntää kieliopin mukaiset käskyt toiminnallisuudeksi.[53]

Tarkkailija[muokkaa | muokkaa wikitekstiä]

Tarkkailija (Observer) Perustuu toimintojen delegointiin olioille käyttäen koostamista. Olioiden välinen tiedonsiirto tapahtuu tarkkailijaa käyttäen, joka muuttaa olion tiedon niissä olioissa, jotka ovat siitä riippuvaisia (yksi-moneen-suhde). Klassinen esimerkki tarkkailijasta on MVC-malli (Model-View-Controller; Luokkamalli-Näkymä-Valvoja-malli).[54]

Vastuuketju[muokkaa | muokkaa wikitekstiä]

Vastuuketju (Chain of Responsibility) perustuu toimintojen delegointiin olioille koostamista käyttäen. Olioiden välinen tiedonsiirto perustuu pyynnön mahdollisesti käsittelevien olioiden (kandidaattioliot) muodostamaan ketjuun, jossa pyyntö käsitellään siinä oliossa, joka voi toteuttaa pyynnön. Pyynnön vastaanottava (käsittelevä) olio ei ole sidottu pyynnön lähettäneeseen olioon.[55]

Välittäjä[muokkaa | muokkaa wikitekstiä]

Välittäjä (Mediator) perustuu toimintojen delegointiin olioille koostamista käyttäen. Eri olioiden välinen tiedonsiirto tapahtuu abstraktia kapseloitua välittäjäoliota käyttäen eli vuorovaikutuksessa olevat oliot eivät voi viitata toisiinsa, edistää olioiden löyhää sidontaa.[56]

Iteraatio[muokkaa | muokkaa wikitekstiä]

Iteraatio (Iterator) perustuu toiminnallisuuden kapselointiin olioon ja funktioiden kutsumiseen tarpeen mukaan. Esimerkiksi tietorakenteen läpikäymiseen peräkkäisjärjestyksessä käytettävä toiminnallisuus kapseloidaan olioon.[57]

Komento[muokkaa | muokkaa wikitekstiä]

Komento (Command) perustuu kutsun kapselointiin abstraktiin olioon ja funktioiden kutsumiseen tarpeen mukaan tätä oliorajapintaa käyttäen.[58]

Muisto[muokkaa | muokkaa wikitekstiä]

Muisto (Memento) perustuu olion sisäisen tilan kapselointiin. Olion sisäinen tila kapseloidaan muisto-olioon, jonka tietoihin on pääsy vain tiedon lähdeoliolla.[59]

Strategia[muokkaa | muokkaa wikitekstiä]

Strategia (Strategy) perustuu olion ohjelma-algoritmien kapselointiin tuotanto-olioihin, joista muodostuu tuotanto-olioperhe. Abstrakti strategiaolio ohjaa pyynnön tuotanto-oliolle.[60]

Tila[muokkaa | muokkaa wikitekstiä]

Tila (State) Perustuu olion tilan (ja tilaan liittyvän vaihtuvan toiminnallisuuden) kapselointiin abstraktin olion valitsemaan tuotanto-olioon. Kun a.oliota kutsutaan, se valitsee sen hetkisen tilansa mukaisen toiminnallisuuden toteuttavan konkreettisen olion.[61]

Vierailija[muokkaa | muokkaa wikitekstiä]

Vierailija (Visitor) Perustuu kutsuvien luokkien yhtäpitävän toiminnallisuuden kapselointiin tuotantoluokkaan ja funktioiden kutsumiseen tarpeen mukaan abstraktia rajapintaluokkaa käyttäen. Kutsuvien luokkien toiminnallisuutta voidaan lisätä ilman niiden luokkarakenteen muuttamista tuotantoluokkia lisäämällä.[62]

Suunnittelumallit ja ohjelmistokehykset[muokkaa | muokkaa wikitekstiä]

Suunnittelumalleilla ja kehyksillä on läheinen yhteys, koska molempien tarkoituksena on tavallisesti lisätä ohjelmiston joustavuutta ja siirrettävyyttä. Suunnittelumalleja voidaan käyttää myös kehysten dokumentointiin perusteltaessa sitä, miksi valittuun suunnitteluratkaisuun on päädytty.[63]

Lähteet[muokkaa | muokkaa wikitekstiä]

  • Gamma, Erich, Helm, Richard, Johnson, Ralph & Vlissides, John. (2001). Olio-ohjelmoinnin Suunnittelumallit. Suomentanut Anita Toivanen. Alkuperäisteos Design Patterns: Elements of Reusable Object-Oriented Software. Helsinki: IT Press. ISBN 951-826-428-7
  • Koskimies, Kai. (2000). Oliokirja. Jyväskylä: Satku - Kauppakaari. ISBN 951-762-720-3
  • Koskimies, Kai & Mikkonen, Tommi. (2005). Ohjelmistoarkkitehtuurit. Jyväskylä: Talemtum. ISBN 952-14-0862-6
Viitteet
  1. Gamma, Helm, Johnson & Vlissides 2001, 4-5.
  2. Koskimies & Mikkonen 2005, 102-103
  3. Koskimies & Mikkonen 2005, 32-35 ja 101
  4. Eriksson & Penker 2000, 221
  5. Koskimies 2000, 245
  6. Gamma, Helm, Johnson & Vlissides 2001, 5.
  7. Eriksson & Penker 2000, 223
  8. Koskimies 2000, 245-247
  9. Koskimies 2000, 247
  10. Koskimies 2000, 245
  11. Koskimies & Mikkonen 2005, 102-103
  12. Eriksson & Penker 2000, 222
  13. Gamma, Helm, Johnson & Vlissides 2001, 2-3 ja 6-8
  14. Gamma, Helm, Johnson & Vlissides 2001, 3
  15. Koskimies & Mikkonen 2005, 106
  16. Gamma, Helm, Johnson & Vlissides 2001, 5
  17. Koskimies & Mikkonen 2005, 105
  18. Koskimies & Mikkonen 2005, 105-106
  19. Gamma, Helm, Johnson & Vlissides 2001, 5
  20. Koskimies & Mikkonen 2005, 105
  21. Koskimies & Mikkonen 2005, 105
  22. Gamma, Helm, Johnson & Vlissides 2001, 3
  23. Koskimies & Mikkonen 2005, 105
  24. Koskimies & Mikkonen 2005, 107
  25. Gamma, Helm, Johnson & Vlissides 2001, 9-11
  26. Gamma, Helm, Johnson & Vlissides 2001, 81
  27. Erikssen & Penker 2000, 223
  28. Gamma, Helm, Johnson & Vlissides 2001, 81
  29. Gamma, Helm, Johnson & Vlissides 2001, 87
  30. Gamma, Helm, Johnson & Vlissides 2001, 87
  31. Gamma, Helm, Johnson & Vlissides 2001, 95
  32. Gamma, Helm, Johnson & Vlissides 2001, 97-99
  33. Gamma, Helm, Johnson & Vlissides 2001, 97-99
  34. Gamma, Helm, Johnson & Vlissides 2001, 105-106
  35. Gamma, Helm, Johnson & Vlissides 2001, 107-108
  36. Gamma, Helm, Johnson & Vlissides 2001, 107
  37. Gamma, Helm, Johnson & Vlissides 2001, 117-118
  38. Gamma, Helm, Johnson & Vlissides 2001, 127
  39. (Gamma, Helm, Johnson & Vlissides 2001, 128
  40. Gamma, Helm, Johnson & Vlissides 2001, 137
  41. Eriksson & Penker 2000, 223
  42. Gamma, Helm, Johnson & Vlissides 2001, 139
  43. Gamma, Helm, Johnson & Vlissides 2001, 151-152
  44. Gamma, Helm, Johnson & Vlissides 2001, 163-164
  45. Gamma, Helm, Johnson & Vlissides 2001, 175-176
  46. Gamma, Helm, Johnson & Vlissides 2001, 185
  47. Gamma, Helm, Johnson & Vlissides 2001, 195-196
  48. Gamma, Helm, Johnson & Vlissides 2001, 207-209
  49. Gamma, Helm, Johnson & Vlissides 2001, 221
  50. Gamma, Helm, Johnson & Vlissides 2001, 221-222
  51. Eriksson & Penker 2000, 223
  52. Gamma, Helm, Johnson & Vlissides 2001, 221-222
  53. Gamma, Helm, Johnson & Vlissides 2001, 211-
  54. Gamma, Helm, Johnson & Vlissides 2001, 211-
  55. Gamma, Helm, Johnson & Vlissides 2001, 211-
  56. Gamma, Helm, Johnson & Vlissides 2001, 211-
  57. Gamma, Helm, Johnson & Vlissides 2001, 211-
  58. Gamma, Helm, Johnson & Vlissides 2001, 211-
  59. Gamma, Helm, Johnson & Vlissides 2001, 211-
  60. Gamma, Helm, Johnson & Vlissides 2001, 211-
  61. Gamma, Helm, Johnson & Vlissides 2001, 211-
  62. Gamma, Helm, Johnson & Vlissides 2001, 211-
  63. Koskimies 2000, 264

Kirjallisuutta[muokkaa | muokkaa wikitekstiä]

  • Gamma, Erich, Helm, Richard, Johnson, Ralph & Vlissides, John. (2007). Design Patterns: Elements of Reusable Object-Oriented Software. Westford, Massachusetts: Addison-Wesley. ISBN 0201633612

Katso myös[muokkaa | muokkaa wikitekstiä]

Aiheesta muualla[muokkaa | muokkaa wikitekstiä]