Olio-ohjelmointi Johdanto suunnittelumalleihin. 1. Yleistä

Samankaltaiset tiedostot
812347A Olio-ohjelmointi, 2015 syksy 2. vsk. IX Suunnittelumallit Proxy, Factory Method, Prototype ja Singleton

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. VII Suunnittelumallit Adapter ja Composite

Ohjelmistotekniikan menetelmät, suunnittelumalleja

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. VIII Suunnittelumallit Observer ja State

Olio-ohjelmointi Suunnittelumallit Proxy, Factory Method, Prototype ja Singleton. 1. Proxy (Edustaja)

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. VI Johdanto suunnittelumalleihin

T SEPA - päiväkirja: Design Patterns. ETL työkalu

Ohjelmistojen mallintaminen luokkamallin lisäpiirteitä

Kertaus: yleistys-erikoistus ja perintä

T SEPA - päiväkirja: Design Patterns. ETL työkalu

Hirviö. Design Patterns

Ohjelmistojen mallintaminen, mallintaminen ja UML

Ohjelmistojen mallintaminen, suunnittelumalleja

Sisällys. Ratkaisumallien historia. Ratkaisumalli. Ratkaisumalli [2] Esimerkki: Composite [2] Esimerkki: Composite. Jaakko Vuolasto 25.1.

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. II Johdanto olio-ohjelmointiin


Tämän lisäksi listataan ranskalaisin viivoin järjestelmän tarjoama toiminnallisuus:

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Oliosuunnittelu. Oliosuunnittelu

SEPA REFAKTOROINTI Antti Ahvenlampi, 57408L Erik Hakala, 57509T

Analyysi, staattinen mallintaminen, kohdealueen malli ja luokkakaavio

Suunnittelumallit (design patterns)

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Rajapinnat ja sisäluokat

Ohjelmistoarkkitehtuurit kevät

Muutamia peruskäsitteitä

Tenttikysymykset. + UML-kaavioiden mallintamistehtävät

Ohjelmistoarkkitehtuurit. Syksy 2010

Suunnittelumalleja, MVC. Juha Järvensivu 2008

SEPA - Design Patterns

Mitä on periytyminen?

Ohjelmistojen mallintaminen Luokkakaaviot Harri Laine 1

Tenttikysymykset. + UML- kaavioiden mallintamistehtävät

Interaktiivisten järjestelmien arkkitehtuuriratkaisu, jolla käyttöliittymä erotetaan sovelluslogiikasta.

Sisällys. Mitä on periytyminen? Yksittäis- ja moniperiytyminen. Oliot ja perityt luokat. Periytymisen käyttö. 8.2

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia.

TIE Samuel Lahtinen. Lyhyt UML-opas. UML -pikaesittely

Graafisen käyttöliittymän ohjelmointi Syksy 2013

Käyttöliittymät II. Käyttöliittymät I Kertaus peruskurssilta. Keskeisin kälikurssilla opittu asia?

Muusta kuin vesisioista

Rajapinnasta ei voida muodostaa olioita. Voidaan käyttää tunnuksen tyyppinä. Rajapinta on kuitenkin abstraktia luokkaa selvästi abstraktimpi tyyppi.

TIE Ohjelmistojen suunnittelu

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Ohjelmistotekniikan menetelmät, luokkamallin laatiminen

Hirviö. Design Patterns

Ohjelmistojen mallintaminen, kesä 2009

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

812341A Olio-ohjelmointi, IX Olioiden välisistä yhteyksistä

Analyysi, staattinen mallintaminen, kohdealueen malli ja luokkakaavio

Sisällys. 11. Rajapinnat. Johdanto. Johdanto

Suunnittelumallien käyttö ohjelmistosuunnittelussa

Ohjelmistojen suunnittelu

Joskus yleistäminen voi tapahtua monen ominaisuuden pohjalta. Myös tällöin voi tulla moniperintätilanteita.

812341A Olio-ohjelmointi, I Johdanto

5. Suunnittelumallit. TTY Ohjelmistotekniikka

12. Kehysarkkitehtuurit

T Henkilökohtainen harjoitus: FASTAXON

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Ohjelmistojen mallintaminen. Luento 11, 7.12.

T Ohjelmistojen määrittely- ja suunnittelumenetelmät Harjoitustyöraportti TNT - Tarkistetaan Ne Tentit Arkkitehtuuri- ja suunnittelumalli

ohjelman arkkitehtuurista.

Ohjelmistoarkkitehtuurit. Kevät

TIE Ohjelmistojen suunnittelu. Luento 8..9: moniperintä

Luokka- ja oliokaaviot

Olio-ohjelmointi Suunnittelumallit Adapter ja Composite. 1. Adapter

Käyttötapausanalyysi ja testaus tsoft

15. Ohjelmoinnin tekniikkaa 15.1

Ohjelmistoarkkitehtuurit Syksy 2009 TTY Ohjelmistotekniikka 1

Aalto Yliopisto T Informaatioverkostot: Studio 1. Oliot ja luokat Javaohjelmoinnissa

15. Ohjelmoinnin tekniikkaa 15.1

Uudelleenkäytön jako kahteen

Suunnittelumallit. OULUN YLIOPISTO Tietojenkäsittelytieteiden laitos Oliosuuntautunut analyysi ja -suunnittelu 27. joulukuuta 2003

Ohjelmoinnin peruskurssien laaja oppimäärä, kevät

Luokkakaavion laatiminen

Ratkaisumallien historia

Tarjolla tänää: Ohjelmiston toteutuksesta. Kuinka tulla hyväksi ohjelmoijaksi? CRC-kortit. Testilähtöinen kehittäminen JOT2007. Uudelleenrakentaminen

Ohjelmistotuotanto. Luento

Olio-ohjelmointi Johdanto olio-ohjelmointiin

Ohjelmistotekniikan menetelmät, luokkamallin laatiminen

UML -mallinnus LUOKKAKAAVIO EERO NOUSIAINEN

Interaktiivisten järjestelmien arkkitehtuuriratkaisu, jolla käyttöliittymä erotetaan sovelluslogiikasta.

2. Olio-ohjelmoinnin perusteita 2.1

Olio-ohjelmointi Suunnittelumallit Observer ja State. 1. Observer (Tarkkailija)

Ohjelmistojen mallintaminen luokkamallin lisäpiirteitä

HELIA 1 (14) Outi Virkki Käyttöliittymät ja ohjlmiston suunnittelu

9. Periytyminen Javassa 9.1

SEPA päiväkirja. Aihe: Suunnittelumallit Tekijät: Tuukka Laakso ja Antti Kettunen

Ohjelmistojen mallintaminen

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

T Ohjelmistojen määrittely- ja suunnittelumenetelmät Harjoitustyöraportti TNT - Tarkistetaan Ne Tentit Analyysimalli

TIE Ohjelmistojen suunnittelu

UML-kielen formalisointi Object-Z:lla

Ohjelmoinnin peruskurssien laaja oppimäärä

Yhteydelle voi antaa nimen kumpaankin suuntaan Sille ei tarvise antaa lainkaan nimeä Yhteysnimen asemasta tai lisäksi voidaan käyttää roolinimiä

Ohjelmistotekniikan menetelmät, UML

Ohjelmistokehykset (software frameworks)

T Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

Ohjelmoinnin peruskurssien laaja oppimäärä

UML Luokkakaavio 14:41

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Transkriptio:

Olio-ohjelmointi Johdanto suunnittelumalleihin Hyvin toimivan olio-ohjelmointiparadigmaa noudattavan ohjelman suunnitteleminen ei ole helppo tehtävä. On löydettävä sopiva luokkarakenne kuvaamaan ratkaistavaa ohjelmointiongelmaa ja toteutettava luokkien väliset suhteet asianmukaisesti. Kokeneet suunnittelijat pyrkivät ratkaisemaan ongelmat niin, että ratkaisu olisi sovellettavissa myös muihin samankaltaisiin tilanteisiin. Kun ratkaisu kuvataan sopivasti, syntyy suunnittelumalli. Tässä esitettävät asiat perustuvat pääasiassa lähteisiin [Bud] (luku 24) ja [Gam]. Viimeksi mainittu kuvaa 23 suunnittelumallia, joista on tullut alan standardeja. Tässä dokumentissa esitetään enimmäkseen asioita, joihin perehdytään myös kurssilla Oliosuuntautunut analyysi ja suunnittelu. 1. Yleistä Suunnittelumalleja on käytetty eri yhteyksissä hyvin kauan. Systemaattisen mallien kuvauksen alkuna voidaan pitää Alexanderin 1970-luvulla luomaa mallikieltä, jota käytettiin rakennusten ja kaavoitusten suunnittelussa ([Ale]). Olio-ohjelmointimalleja voidaan tunnistaa ainakin jo 1980- luvulta, jolloin Smalltalk-ympäristön graafisen käyttöliittymän toteutuksessa käytettiin ns. Model-View-Controller-mallia. Siitä voidaan eristää ainakin kaksi yleistä suunnittelumallia. Olio-ohjelmoinnissa sovellettavien mallien kuvauksia alettiin julkaista 1990-luvulla; merkittävin teos tältä ajalta on ns. Gang of Fourin (Gamma, Helm, Johnson, Vlissides) julkaisu Design Patterns: Elements of Reusable Object-Oriented Software ([Gam]). Suunnittelumallista voidaan tunnistaa yleensä seuraavat neljä pääosaa: 1. Mallilla on oltava osuva nimi, jota käytetään siitä puhuttaessa. Nimen täytyy liittyä mallin ominaispiirteisiin. Tällöin nimi lisää sanastoa, jota käytetään kommunikoitaessa toisten suunnittelijoiden kanssa. 2. Malliin liittyvä ongelma kuvaa tilanteita, joihin mallia voi soveltaa. Voidaan kuvata tiettyjä, mallin avulla ratkeavia suunnitteluongelmia tai hankalia luokkarakenteita, joita mallin käyttäminen parantaa. Voidaan myös antaa ehtoja, joiden vallitessa mallia on järkevää käyttää. 3. Ratkaisu kuvaa mallin olennaiset osat, niiden suhteet, vastuut ja yhteistoiminnan. Yleensä ei kuvata konkreettista toteutusta, vaan annetaan abstrakti kuvaus siitä, miten luokkien ja olioiden rakenne ja toiminta ratkaisee suunnitteluongelman. 4. Seuraukset kuvaavat mihin ratkaisun soveltaminen johtaa ja minkälaisia kompromisseja sen soveltaminen aiheuttaa. Nämä on huomioitava ratkaisumallia valittaessa. Riippuu näkökulmasta ja käytettävistä välineistä, mitä voidaan pitää suunnittelumallina. Jos olisimme tuomitut käyttämään ei-oliokieltä, saattaisivat periytyminen ja monimuotoisuus olla suunnittelumalleja. Koska käytössä on kieliä, joissa ne ovat perusrakenneosia, ei mainittuja asioita yleensä pidetä malleina. Näin ollen valittu ohjelmointikieli vaikuttaa käytettäviin malleihin, koska kielen valinta vaikuttaa näkökulmaan, josta ongelmaa tarkastellaan. Toisaalta myöskään hyvin monimutkaisia ohjelman kuvauksia ei lasketa malleiksi. Tässä käsiteltävät suunnittelumallit kuvaavat rakenteen, jonka luokat ja oliot yhteistyöllään ratkaisevat jonkin yleisen, tietyssä yhteydessä esiintyvän ongelman. 1

2. MVC-malli 1980-luvulla esitellyssä Smalltalk-ohjelmointijärjestelmässä käytettiin ns. MVC (Model-View- Controller)-mallia käyttöliittymän rakentamisessa. Malli koostuu luokkien kolmikosta, jonka toiminta sisältää ainakin kahdenlaisia suunnittelumalleja. Model on sovellusolio, View on ruudun näkymä ja Controller määrittelee tavat, joilla käyttöliittymä reagoi käyttäjän syötteisiin. MVC-mallin perusidea on eristää nämä kolme oliota toisistaan. Näkymä ja malli erotetaan toisistaan toteuttamalla luokkien välille rekisteröitymiseen ja ilmoittamiseen perustuva protokolla. Samaa mallia voi vastata useita näkymiä, jotka rekisteröityvät tietyn mallin tarkkailijoiksi. Kun malli muuttuu, Controller ilmoittaa muutoksesta kaikille mallin tarkkailijoille, jotka voivat päivittää itsensä vastaamaan mallin tilaa. Esimerkiksi seuraavassa kuviossa mallia tarkkailee kolme näkymää. Kuvioon ei ole merkitty Controlleria. Kuva 1. Esimerkki MVC-mallista. (Lähde: [Gam]) Asetelma voidaan yleistää tilanteeseen, jossa eristetään oliot toisistaan siten, että muutos yhden olion tilassa vaikuttaa muiden olioiden tiloihin. Näin syntyykin suunnittelumalli, joka on sovellettavissa moniin tapauksiin. Tätä mallia kutsutaan Tarkkailija- eli Observersuunnittelumalliksi. Käyttöliittymä koostuu tyypillisesti komponenteista, jotka sisältävät käyttöliittymäelementtejä. Monimutkaisissa käyttöliittymissä komponenttien sisältämät elementit voivat olla edelleen komponentteja, jotka sisältävät käyttöliittymäelementtejä jne. MVC-mallissa näkymät voivat tämän vuoksi sisältyä toisiin näkymiin ja yhdistettyjä näkymiä käsitellään niin kuin yksinkertaisia komponenttejakin. Tämäkin asetelma voidaan yleistää: Toteutetaan luokkarakenne, jonka olioiden muodostamia ryhmiä voidaan käsitellä kuten yksittäistä oliota. Taas kehittyy monissa yhteyksissä sovellettava suunnittelumalli, ns. Kooste- eli Composite- 2

malli. MVC-mallin rakenteesta voidaan tunnistaa muitakin hyväksi havaittuja suunnittelumalleja (ks. esim. [Gam], Introduction - Design Patterns in Smalltalk MVC). 3. Suunnittelumallin kuvaaminen Kun suunnittelumalli on tunnistettu, se on pystyttävä kuvaamaan riittävän hyvin, jotta muutkin voivat käyttää mallia. Yleensä malli kuvataan luonnollisella kielellä, jota täydennetään UMLkaavioilla sekä esimerkkikoodilla. Alla on mainittu tärkeimmät Gamman et. al. ([Gam]) mallista kuvaamat seikat Mallin nimi ja luokittelu Hyvin valittu nimi auttaa mallin tunnistamisessa ja siitä puhumisessa. Gamma et. al. jakavat mallit olioiden luomiseen liittyviin malleihin, rakenteellisiin malleihin ja käyttäytymiseen liittyviin malleihin. Tarkoitus Lyhyt kuvaus mallin toiminnasta ja siitä, minkälaisiin suunnitteluongelmiin se soveltuu ratkaisuksi. Perustelu Skenaario, joka kuvaa millä tavoin luokkien ja olioiden rakenne ratkaisee suunnitteluongelman. Soveltuvuus Kuvaa tilanteita, joihin mallia voidaan soveltaa. Rakenne Mallin luokkakaavio. Saattaa myös sisältää vuorovaikutuskaavioita. Osallistujat Mallin luokat ja oliot sekä niiden vastuut. Yhteistyösuhteet Toimijoiden yhteistoiminta vastuidensa toteuttamisessa. Seuraukset Kuvaa, mihin ratkaisun soveltaminen johtaa ja minkälaisia kompromisseja sen soveltaminen aiheuttaa. Voi myös kuvata, mitä ohjelman ominaisuuksia voidaan muutella mallin toteutusta häiritsemättä. Toteutus Antaa vihjeitä mallin implementointiin, listaa hankaluuksia joihin on varauduttava ja tekniikoita, joita voidaan käyttää implementoinnissa. Esittää myös mahdollisia kieliriippuvuuksia. Lisäksi annetaan mahdolliset muut nimet, joilla malli tunnetaan sekä malliin läheisesti liittyviä muita malleja. Malliin voidaan myös liittää esimerkkikoodia ja tunnettuja reaalimaailman käyttötapauksia. 3

4. Suunnittelumalleille asetettuja tavoitteita Suunnittelumallien toivotaan parantavan olio-ohjelmien laatimista useilla tavoilla. Ensinnäkin suunnittelumallien luokittelu ja niiden nimeäminen antaa suunnittelijoille yhtenäisen sanaston, jota voidaan käyttää pohdittaessa ratkaisuja vastaan tuleviin ongelmiin. Yleisesti katsotaan, että käytössä oleva sanasto vaikuttaa ajatteluun: suunnittelumalleja apuna käyttäen voidaan ongelmaa käsitellä korkeammalla abstraktiotasolla. Yleisimpien suunnittelumallien tunteminen auttaa ymmärtämään ohjelmakoodia paremmin, koska suuri osa laajoista oliopohjaisista ohjelmista käyttää suunnittelumalleja. Mikäli koodin dokumentoinnista käy ilmi, mitä mallia on käytetty, ohjelman rakenne ja toiminta aukeaa mallin tuntevalle lukijalle helpommin. Suunnittelumallien toivotaan lisäksi täydentävän muita oliosuuntautuneita suunnittelumetodeja, jotka eivät samalla lailla hyödynnä kokeneiden suunnittelijoiden tietoja. Ohjelman kehittyessä ja joutuessa mukautumaan uusiin vaatimuksiin, se on joskus refaktoroitava, eli osia sen luokkarakenteesta on suunniteltava uudelleen. Tällöin suunnittelumalleista on hyötyä uuden luokkarakenteen laatimisessa. Lisäksi hyväksi havaittujen mallien soveltaminen jo kehityksen varhaisessa vaiheessa voi poistaa myöhemmän refaktoroinnin tarpeen. 5. Suunnitteluongelmien suhde suunnittelumalleihin Suunniteltaessa oliosuuntautunutta ohjelmaa sen oliorakenne muodostuu pääosin luonnollisella tavalla mallista, joka kohdejärjestelmästä on tehty. Yleensä näin löydetään oliot, joilla on suora vastine reaalimaailmassa. Monesti ohjelmaan on kuitenkin toteutettava toimintoja, joilla ei ole vastinetta ulkomaailmassa. Ohjelmassa voi esiintyä jokin algoritmi tai toiminto, joka on välttämätön halutun ratkaisun saamiseksi. Silloin tarvitaan olio tai joukko olioita toteuttamaan tämä. On olemassa suunnittelumalleja (esimerkiksi Strategy eli Strategia), jotka avustavat ohjelmoijaa löytämään tarkoituksenmukaisen oliorakenteen. Monet suunnittelumallit ratkaisevat myös ongelmia, joita kohdataan, kun ohjelmassa on luotava olioita erityisen suuria määriä ja käsiteltävä niitä. Tällaisia ovat esimerkiksi Facade- eli Julkisivu- ja Flyweight- eli Hiutalemallit. Joskus syntyy erityisen massiivisia olioita; on olemassa malleja, jotka kuvaavat miten niitä voidaan jakaa osiksi. Ohjelmissa kohdataan myös tilanteita, jolloin on luotava olio, jonka tarkkaa tyyppiä ei käännösaikana tunneta; jotkin suunnittelumallit vastaavat tällaiseen ongelmaan (Builder eli Rakentaja, Abstract Factory eli Abstrakti tehdas) samoin kuin jonkin luokkahierarkian olioiden läpikäymiseen (Visitor eli Vierailija, Command eli Komento). Luokkien rajapintojen suunnittelussa avustavia malleja on myös olemassa. Edellä oli kysymys enimmäkseen ohjelman olioiden tunnistamisesta ja niiden keskinäisen toiminnan suunnittelusta. Kun rakennetta lähdetään implementoimaan, on suunniteltava olioiden ominaisuudet eli määriteltävä luokat, joista olioita luodaan. Gamman et al. ([Gam]) mukaan kaikkein olennaisin asia uudelleenkäytettävän olio-ohjelman suunnittelussa on keskittyä nimenomaan rajapintoihin. Luokkahierarkian kantaluokan olisi tästä syystä oltava abstrakti ja hierarkian olioita tulisi käsitellä ainoastaan tämän luokan määrittelemän rajapinnan kautta. Näin ohjelman osajärjestelmien väliset riippuvuudet vähenevät. He esittävät tämän periaatteen muodossa Program to an interface, not an implementation. Luontimallit eli olioiden 4

luomiseen liittyvät mallit (Factory Method eli Tehdasmetodi, Prototype eli Prototyyppi, Singleton eli Ainokainen) varmistavat, että tätä periaatetta käytetään. Olio-ohjelmoinnin tulisi suosia uudelleenkäytettävyyttä. Ohjelmaa rakennettaessa luokkien välille syntyy helposti riippuvuuksia, jotka haittaavat luokkien siirtämistä toiseen yhteyteen. Periytyminenkin voi olla rasite, jos jotakin aliluokkaa haluttaisiin käyttää uudelleen. Aliluokka perii kuitenkin yliluokkansa piirteet, joita ei voi muuttaa, ellei kirjoita koko rakennetta uudelleen. Monessa tapauksessa kannattaakin käyttää koostetta: lisätään toisen luokan olio luokkaan attribuutiksi. Näin voidaan rajoittaa yhden luokan vastuut yhteen toimintaan. Gamman et al. ([Gam]) esittämän periaatteen mukaan ohjelmoijan tulisikin suosia koosteita perimisen sijaan: Favor object composition over class inheritance. Myös useimmissa suunnittelumalleissa käytetään koostamista ahkerasti. Delegointi liittyy olennaisesti koostamiseen: delegoinnissa jokin olio täyttää sille esitetyn pyynnön ohjaamalla sen edelleen jollekin osaoliolleen. Delegointi voi dynaamisen luonteensa vuoksi tehdä ohjelmakoodista vaikeammin ymmärrettävää, mutta jos sitä käytetään standardimaisten suunnittelumallien implementoinnissa, ongelma poistuu. On useita suunnittelumalleja, joiden toiminta perustuu nimenomaan delegointiin. Esimerkiksi Vierailija- eli Visitor-mallissa tehdään oliorakenteen kaikille olioille jokin operaatio, jonka suorittaminen on delegoitu erityiselle Visitor-oliolle. Jotkin ohjelmat ovat vaikeasti hahmotettavia, koska niiden staattinen muoto ei kerro kaikkea olennaista niiden toiminnasta. Niissä voidaan luoda monimutkaisia suorituksenaikaisia rakenteita, joiden käyttäytyminen ei selviä helposti staattisesta luokkarakenteesta. Ohjelmaa voi ymmärtää paremmin, mikäli tuntee sopivia suunnittelumalleja. Esimerkiksi Kooste-mallia käytetään monimutkaisten ajonaikaisten rakenteiden luomiseen. Toisaalta Tarkkailija-mallia käyttävää ohjelmaa on vaikea ymmärtää koodia lukemalla, ellei tunne mallin rakennetta. Ohjelmaan kohdistuu sen eliniän aikana erilaisia muutospaineita. Hyvin suunniteltu ohjelma voi taipua kohtuullisilla muutoksilla vaatimusten muuttumiseen. Ohjelma olisikin hyvä suunnitella alun perin sellaiseksi, että osia siitä voidaan muokata aiheuttamatta suuria muutosvaatimuksia toisiin osiin. Taitavasti käytetyt suunnittelumallit voivat auttaa siinä: yleensä jokainen malli antaa ohjelman muille osille ainakin jonkinlaisia vapauksia. Lisäksi mallin kuvauksen tulisi kuvata rajoitteet. Mainittakoon tässä muutamia ongelmia, jotka haittaavat ohjelman sujuvaa muokkaamista: 1. Kun luodaan olioita suoraan jostakin luokasta käyttämällä luokan nimeä, sitoudutaan sen implementaatioon eikä rajapintaan. Mikäli annetaan olion luominen jonkin toimijan vastuulle, voidaan implementaatiota muuttaa. Epäsuoraan olion luomiseen käytetään esimerkiksi Prototyyppi- eli Prototype-suunnittelumallia. 2. Riippuvuus tietyistä algoritmeista. Eräiden suunnittelumallien avulla algoritmit voidaan eristää niiden käyttäjistä. Esimerkiksi Template Method- eli Operaatiorunko-malli on tällainen. 3. Olioiden ja luokkien väliset riippuvuudet johtavat usein siihen, että yksittäistä ohjelman osaa on vaikea muuttaa tekemättä muutoksia moniin muihin kohtiin. Useat suunnittelumallit löyhentävät riippuvuuksia; mm. jo aiemmin mainittu Observer-malli tekee näin. 4. Joskus tulisi käyttää valmista luokkaa sellaisessa yhteydessä, johon sen rajapinta ei suoraan sovellu tai rajapinnan käyttö on vaivalloista. Mikäli luokkaa ei voi muuttaa, on ongelma ratkaistava muuten. Adapter- eli Sovitin-suunnittelumallia käytetään usein tällaisissa tilanteissa: tehdään erityinen sovitinluokka toimijoiden välille. 5

6. Suunnittelumallien luokittelu Suunnittelumalleja voidaan luonnollisesti luokitella hyvin monin eri tavoin. Gamma et al. ([Gam]) jakavat mallinsa taulukoksi kahden kriteerin perusteella: 1. Mallin tarkoitus (olioiden luominen, rakenteellinen, käyttäytyminen) 2. Mallin kohde (käytetäänkö pääasiassa luokkia vai olioita) Näin saadaan Gamman et. al. suunnittelumalleille seuraava taulukko: Kuva 3. Mallien luokittelu. (Lähde: Lasse Harjumaan luentokalvot) Luokkamallit keskittyvät luokkien välisiin suhteisiin, jotka määräytyvät käännösaikana. Näin ollen nämä mallit ovat luonteeltaan enimmäkseen staattisia. Oliomallit puolestaan käsittelevät olioiden välisiä suhteita, jotka voivat muuttua ohjelman suorituksen aikana. Siten oliomallit ovat luonteeltaan dynaamisempia kuin luokkamallit. Olioiden luomiseen liittyvät luokkamallit siirtävät olion luomisen aliluokkiin, kun taas vastaavat oliomallit siirtävät sen jonkin olion vastuulle. Rakenteelliset luokkamallit käyttävät periytymistä luokkien rakentamisessa; rakenteelliset oliomallit kuvaavat tapoja yhdistellä olioita. Käyttäytymiseen perustuvat luokkamallit kuvaavat, miten periytymistä käyttämällä voidaan toteuttaa algoritmeja ja erilaisia suorituspolkuja. Vastaavat oliomallit kuvaavat, miten joukko olioita voi yhteistuumin suorittaa jonkin tehtävän. 7. Suunnittelumallin valinnasta ja käyttämisestä Suunnittelumalli on tietysti valittava niin, että se ratkaisee kohdatun ongelman. Jotta sopiva malli pystytään löytämään, on tutustuttava tapoihin, joilla suunnittelumalleja sovelletaan. Oikean mallin valitseminen vaatii kokemusta ja erilaisten ratkaisujen tuntemusta sekä mallien ominaisuuksien ja niiden suhteiden tuntemista. 6

Gamma et. al ([Gam]) antavat ohjeellisen toimintatavan valitun mallin soveltamiseksi: 1. Tutustu ensin malliin kokonaiskuvan saamiseksi. Sovellettavuus ja seuraukset vahvistavat, että ongelmaan soveltuva malli on valittu. 2. Tutustu huolellisesti mallin kuvauksesta osallistujiin, rakenteeseen ja yhteistoimintaan. 3. Tutki, onko mallista annettu esimerkkikoodia, jotta näet konkreettisen esimerkin sen implementoinnista. 4. Valitse mallin toimijoille sovelluskontekstiin sopivat nimet. Tämä auttaa mallin implementoinnissa. 5. Määrittele luokat. Toisin sanoen konstruoi niiden rajapinnat, niiden perimissuhteet sekä määrittele luokkiin jäsenmuuttujat. Tunnista uusien luokkien vaikutukset sovelluksen aiemmin määriteltyihin luokkiin ja tee niihin tarvittavat muutokset. 6. Valitse mallin luokkien metodeille sovelluskontekstiin sopivat nimet. Sopivat valinnat lisäävät koodin luettavuutta. 7. Implementoi operaatiot toteuttamaan mallin osallistujien yhteistoiminta ja vastuut. Suunnittelumallia ei kuitenkaan ole syytä soveltaa vain soveltamisen ilosta; mallin toteuttaminen lisää yleensä ohjelman kompleksisuutta. On arvioitava mallin mukanaan tuomat hyödyt sen mahdollisiin haittavaikutuksiin nähden. Päätöksen tekemisessä voi auttaa mallin seurauksiin tutustuminen. Lähteet [Ale] Alexander, Ishikawa, Silverstein, Jacobson, Fiksdahl-King, Shlomo Angel. A Pattern Language. Oxford University Press, New York, 1977 [Bud] Budd, Timothy A: An Introduction to Object-Oriented Programming, Addison-Wesley 2002 [Gam] Gamma, Helm, Johnson, Vlissides: Design Patterns: Elements of Reusable Object- Oriented Software, Addison-Wesley 1995 7