SUUNNITTELUMALLIT

Mika Ylikangas

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

12.2.2002

Joensuun yliopisto

Tietojenkäsittelytiede

Laudaturseminaari

 

1. Johdanto

Oliopohjaisten järjestelmien arkkitehtuuri sisältää usein ratkaisuja, jotka ovat toistuneet useissa aikaisemmissa järjestelmissä. Tämä uudelleenkäyttö on usein tiedostamatonta ilman mitään suuremman asiayhteyden oivaltamista. Lisäksi onnistuneet ratkaisut ovat hyvin usein pysyneet pienen piirin sisällä ilman että niitä olisi välitetty eteenpäin käytettäväksi edelleen.

Tämä esitelmä tarkastelee suunnittelumalleja (Design Patterns). Suunnittelumalli tarjoaa määrämuotoisen tavan luetteloida oliopohjaisissa järjestelmissä käytettäviä vakioratkaisuja. Aluksi tarkastelemme suunnittelumallin käsitettä. Tämän jälkeen käymme läpi suunnittelumallin rakenteen ja esimerkin. Käymme läpi perusteet, joilla suunnittelumalleja jaotellaan ryhmiksi. Lopuksi tarkastelemme erilaisia ryhmiä ja näihin kuuluvia suunnittelumalleja.

2. Suunnittelumalli

Itse suunnittelumallin käsite on lainattu rakennusarkkitehtuurista. Gamma et al. (1994) määrittelevät suunnittelumallin seuraavasti:

Suunnittelumalli nimeää, tarjoaa taustatietoa ja selittää yleisen rakenteen, joka ratkaisee oliopohjaisissa järjestelmissä usein toistuvan suunnitteluongelman. Se kuvaa ongelman, ratkaisun ja kertoo milloin ratkaisua voidaan soveltaa ja mitkä ovat tämän ratkaisun seuraukset. Se antaa myös toteutusohjeita ja esimerkkejä. Ratkaisu on yleinen kokoelma olioita ja luokkia, joita sovelletaan ja räätälöidään ratkaisemaan ongelma kussakin käytännön tilanteessa.

Tulkinta siitä, mikä on ja mikä ei ole suunnittelumalli, on määritelmästä huolimatta tulkinnanvarainen. Gamma et al. (1994) mukaan suunnittelumallin käsitteeseen eivät kuulu abstraktit tietotyypit, koska ne ovat valmiiksi koodattuja luokkia joita voidaan käyttää sellaisenaan. Myöskään monimutkaiset kuvaukset kokonaisista alijärjestelmistä tai ohjelmista eivät kuulu suunnittelumallin käsitteeseen.

3. Suunnittelumallin muoto

Suunnittelumalli koostuu ainakin neljästä osasta:

  1. Suunnittelumallin nimi
  2. Ongelma, johon suunnittelumallia sovelletaan
  3. Ratkaisu, joka kuvaa ongelman ratkaisussa käytettävät osat
  4. Seuraukset, joita suunnittelumallin käytöstä aiheutuu

Seuraavassa esimerkissä käymme läpi yhden suunnittelumallin:

Etusivu (Facade)

Tarkoitus

Tarjoaa yhtenäisen liittymän alijärjestelmien erilaisiin liittymiin. Etusivu tarjoaa korkeamman tason liittymän tehden alijärjestelmästä helppokäyttöisemmän.

Ryhmä

Olio - Rakennemalli

Taustatietoja

Järjestelmän jakamisen alijärjestelmiin auttaa vähentämään kompleksisuutta. Yleisesti tunnustettu suunnittelun tavoite on minimoida tiedonsiirtokanavat ja riippuvuudet alijärjestelmien väliltä. Käytetään esimerkkinä ohjelmointikielen kääntäjää. Kääntäjä tarvitsee useiden muiden luokkien lisäksi syntaksin tarkastajan. Erikoistunut ohjelmointikäyttöön tarkoitettu editori tarvitsee suoraa pääsyä syntaksin tarkastajaan ja muihin kääntäjän muodostaviin luokkiin. Kuitenkin useimmissa tapauksissa monikäyttöinen, matalan tason liittymä vain vaikeuttaa kääntäjän käyttöä.

Soveltuvuus

Käytä etusivua kun haluat tarjota yksinkertaisen liittymän monimutkaiseen alijärjestelmään. Monet alijärjestelmät liittymät muuttuvat kehittyessään. Etusivu tarjoaa yksinkertaisen vakionäkymän alijärjestelmään, joka on tarpeeksi hyvä useimmille käyttäjille. Loput voivat käyttää alijärjestelmää suoraan.

Osallistujat

Etusivu (ohjelmointikielen kääntäjä)

Alijärjestelmän luokat kuten syntaksin tarkastaja yms.

Käytön seuraukset

Etusivu tarjoaa seuraavat hyödyt:

    1. Etusivu edesauttaa väljää riippuvuutta alijärjestelmän käyttäjän ja alijärjestelmän välillä.
    2. Etusivu ei estä käyttämästä suoraan alijärjestelmän luokkia. Tämä tarjoaa mahdollisuuden valita helppokäyttöisyyden ja muokattavuuden välillä.

Toteutus

Harkitse seuraavia seikkoja toteuttaessasi etusivua.

Alijärjestelmän käyttäjän ja alijärjestelmän riippuvuutta voidaan vähentää entisestään määrittämällä etusivusta abstraktin luokan. Tällöin alijärjestelmän eri muunnoksia voidaan käyttää ilman, että alijärjestelmän käyttäjään tarvitsee tehdä muutoksia.

 

4. Suunnittelumallien luokittelu

Suunnittelumallien luokittelu tulee tärkeäksi silloin, kun suunnittelumalleja kootaan luetteloiksi. Tämä auttaa mahdollisten ratkaisuvaihtoehtojen rajaamisessa ja parhaan ratkaisun löytämisessä. Gamma et al. (1994) kuvaa kaksi tapaa luokitella suunnittelumalleja.

Ensimmäisessä tavassa suunnittelumalleja luokitellaan kahden kriteerin perusteella. Ensimmäinen kriteeri, tarkoitus (purpose), kuvaa mitä suunnittelumalli tekee. Toinen kriteeri, ympäristö (scope), kuvaa soveltuuko suunnittelumalli pääsääntöisesti luokkiin vai olioihin. Suunnittelumalli voi soveltua tarkoitukseltaan joko luontimalliksi (creational pattern), rakennemalliksi (structural pattern) tai käyttäytymismalliksi (behavioral pattern). Mallin ympäristö voi olla joka luokka tai olio. Luokkamallit käsittelevät perintää ynnä muuta "käännösaikaista" tietoa. Oliomallit käsittelevät olioiden välisiä suhteita ja työnjakoa.

Toisessa tavassa malleja luokitellaan mallien välisen sukulaissuhteen perusteella. Esimerkiksi etusivu (facade) on usein myös yksinäinen (singleton). Oikea suunnittelumalli paikannetaan seuraamalla näitä suhteita.

4.1 Luontimallit

Luontimalleja käytetään abstrahoimaan luokan ilmentymien luonti. Seuraavassa kuvataan muutamaa luontimallia:

Malli

Luokka

Tarkoitus

Abstrakti tehdas

(Abstract Factory)

Olio - Luontimalli

Tarjoaa liittymän olioiden luomiseen, ilman että konkreettista luokkaa tarvitsee määrittää luomisen aikana.

Prototyyppi

(Prototype)

Olio - Luontimalli

Tarjoaa keinon olioiden luomiseen käyttämällä prototyyppioliota josta luodaan kopioimalla uusia olioita.

Luontimallit auttavat ratkaisemaan muun muassa seuraavanlaisia käytännön ongelmia:

4.2 Rakennemallit

Rakennemallit liittyvät olioiden välisiin suhteisiin ja siihen, kuinka olioita yhdistelemällä saadaan uusia toimintoja. Seuraavassa kuvataan muutamaa rakennemallia:

Malli

Luokka

Tarkoitus

Silta

(Bridge)

Olio – Rakennemalli

Tarjoaa keinon käyttää liittymää siten, että liittymän toteutusta voidaan vaihtaa ajonaikana.

Kärpässarjalainen

(Flyweight)

Olio – Rakennemalli

Tarjoaa keinon käyttää todella suuria määriä yksinkertaisia olioita tehokkaasti käyttämällä olioiden jakamista.

Rakennemallit auttavat ratkaisemaan muun muassa seuraavanlaisia käytännön ongelmia:

4.3 Käyttäytymismallit

Käyttäytymismallit käsittelevät olioiden välisiä suhteita ja vastuita. Seuraavassa kuvataan muutamaa käyttäytymismallia:

Malli

Luokka

Tarkoitus

Iteraattori

(Iterator)

Olio –

Käyttäytymismalli

Tarjoaa yhtenäisen tavan käydä läpi järjestyksessä tietorakenteen olioita ilman, että varsinaista tietorakennetta tarvitsee paljastaa.

Tarkkailija

(Observer)

Olio –

Käyttäytymismalli

Tarjoaa keinon muodostaa olioiden välisen suhteen, jonka avulla tieto olion tilan muuttumisesta välitetään kiinnostuneille olioille.

Käyttäytymismallit auttavat ratkaisemaan muun muassa seuraavanlaisia käytännön ongelmia:

 

5. Loppupäätelmät

Suunnittelumallit auttavat ymmärtämään aikaisemmin onnistuneita ratkaisuja. Lisäksi suunnittelumallit parantavat dokumentaatiota ja nostavat suunnittelun abstraktiotasoa tarjoamalla käyttöön yleisesti tunnetun termistön (Gamma et al. 1994). Hieman toisesta näkökulmasta katsottuna suunnittelumallien edut tulevat ilmi, kun malleja järjestetään kokoelmiksi. Määrämuotoisuuden ansiosta eri mallit ovat keskenään vertailtavissa, jolloin oikean ratkaisun löytäminen käsillä olevaan ongelmaan helpottuu. Toisaalta suunnittelumalleja ei voi soveltaa jokaiseen ohjelmointiongelmaan, koska ratkaisua ei välttämättä tarvitse uudelleenkäyttää.

Viiteluettelo

Gamma, E. & Helm, R. & Johnson, R. & Vlissides, J.: Design Patterns – Elements of Reusable Object-Oriented Software, Addison-Wesley, 1994.