Suunnittelumallit ja kehykset

Suunnittelumallit

Suunnittelumalli on valmis ratkaisu johonkin usein esiintyvään ongelmaan. Ne merkitsevät ohjelmiston suunnittelulle samaa kuin luokkakirjastot ohjelmoinnill.

Ohjelmia kirjoitettaessa niihin mallinnetaan yleensä ongelmamaailman logiikkaa melko paljon. Esimerkiksi luokkina voi olla tosimaailman asioita jolla ohjelmisto ratkoo enneltamääritettyjä ongelmia. Kuitenkin viimeistään ohjelmaa toteutettaessa tulee ilmi luokka- ja oliorakenteita, joille ei löydy tosielämän vastinetta. Tässä tulevat apuun muutamat hyvin tutkitut, valmiiksi sovelletut sekä tunnetut suunnittelumallit. Suunnittelumalleja käyttäessä suunnittelija tietää osasten roolit, niille tarvittavat lähtökohdat sekä millaisia seurauksia mallin käytöstä on kokonaisuutta ajatellen. Myöskin käyttämällä yleisesti tunnettuja malleja suunnittelija voi puhua muiden suunnittelijoiden kanssa paljon nopeammin siitä millaista ratkaisua hän on ajamassa takaa.

Oliokielissä mallit kuvaavat yleensä eri olioiden ja luokkien välistä kommunikaatiota ja omistussuhteita. Käytettävät mallit riippuvat millä tasolla kielen ohjelmoija joutuu suunnittelemaan. Oliokielissä yleisiä malleja ovat vaikkapa "Ainokainen(Singleton)" ja "Proxy", proseduraalisissa kielissä suunnittelumalleja voisivat olla vaikkapa "Perintä" ja "Polymorfismi". Konekielessä päteviksi suunnittelumalleiksi voisi mieltää "muuttujan" ja "silmukan".

Suunnittelumalli (Design Pattern):
= tapa suunnitella ohjelmiston osa tietyn usein esiintyvän ongelman ratkaisemiseksi.

Suunnittelumalli koskee yleensä muutamia luokkia ja niiden välisiä suhteita. Ovat tavallisesti sovellusalueesta riippumattomia, mutta voi myös olla johonkin tiettyyn sovellusalueeseen liittyvä malli.

Suunnittelumallin soveltamistaso voi vaihdella aina detaljitason mallista kokonaisen arkkitehtuuritason kuvaamaan malliin. Soveltamisen tulisi aina lähteä tietyn ongelman identifioinnista, siis pelkästään se, että sovelluksessa on käytetty suunnittelumalleja, ei tee siitä välttämättä laadukasta.

Suunnittelumalli annetaan yleensä dokumenttina, joka voi sisältää esim. mallin tarkoituksen, mahdolliset sovelluskohteet, rakenteen (esim. UML), edut ja haitat, sovellusesimerkit.

Antisuunnittelumallit (antipattern):
Epätoivottavat suunnitteluratkaisut. Auttavat virheellisen ratkaisumallin havaitsemista koodissa.

Suunnittelumallien luokittelu
Pieni Oliokirja sekä Design Patterns(Gamma,Helm,Johnson,Vlissides,1995,Addison Wesley,sivu 10) jakaa sunnittelumallit kolmeen ryhmään tarkoituksensa perusteella:

Kehykset

Ohjelmistokehys (framework):
= Kiinteästi toisiinsa liittyvien luokkien ja /tai rajapintojen kokoelmaa, joka toteuttaa tietyn ohjelmistoperheen perusarkkitehtuurin.

Kehyksen tarkoituksena on saavuttaa korkea uudelleenkäytön aste. Pyritään uudelleenkäyttämään kokonaisia sovellus- tai komponenttiperhettä yksittäisten luokkien tai rutiinien sijaan.

Kehyksestä saadaan yksittäinen sovellus tai komponentti erikoistamalla. Tätä varten kehyksellä on erikoistamisrajapinta, joka kertoo, mitkä osat kehyksessä ovat muunneltavia (muunneltavat osat kerrotaan yleensä dokumentoinnissa). Kehyksellä on tavallisesti myös palvelurajapinta.

Jos kehystyksen erikoisuus vastaa täydellistä sovellusta, niin tällöin puhutaan sovelluskehyksestä (application framework). Sovelluskehys on siis ohjelmisto, joka sisältää tietyn tyyppisten sovellusten perusratkaisut. Esimerkkinä sovelluskehyksistä on AWT.

Javassa erikoistaminen voidaan toteuttaa esim. periyttämisellä, rajapinnoilla tai Java 1.5:n uutena ominaisuutena: geneerisillä luokilla.

Kehyksillä ja suunnittelumalleilla on läheinen yhteys. Nimittäin monien suunnittelumallien päämääränä on lisätä ohjelmiston joustavuutta ja yleisyyttä. Siksi nämä suunnittelumallit ovat usein käyttökelpoisia ratkaisuja kehysarkkitehtuureissa. Esim. Tarkkailija.

Suunnittelumalleja on käytetty myös kehysten dokumentoimiseen – Ne selittävät miksi kehyksessä on käytetty tiettyjä suunnitteluratkaisuja.


Teksti otettu pääosin lähteistä

Koskimies: Pieni Oliokirja
Design Patterns(Gamma,Helm,Johnson,Vlissides,1995,Addison Wesley)

Strategia -mallin idea ja toteutus

Kirppusirkus! (particle demonstration)

Kirppujen keskinäinen vuorovaikutus päätetään lennossa. Vanhoissa proseduraalisissa kielissä (C, Pascal) ratkaisuna olisi voinut olla switch-case lauseet tai funktio-osoittimet. Olioperustaisissa kielissä on mahdollista kapseloida vaihtuvat algoritmit omaksi luokakseen. Metodien kapseloinnilla voi lisätä uusia, melko monimutkaisiakin funktioita järjestelmään helposti. Tässä ohjelmassa kirppujen välisten vuorovaikutuksten laskemistavat ovat kapseloitu omiin luokkiinsa. Toisena esimerkkinä kävisi vaikkapa erilaisten järjestämisalgoritmien kapselointi omiin luokkaansa. Algoritmiryhmillä tulee kuitenkin olla yhtenäinen tarkoitus joka ilmenee yhtenäisinä rajapintoina.

Suunnittelumallien maailmassa tämänlaista ratkaisua kuvataan nimellä Strategia(Strategy). Alla on strategian kaavio, joka on miltei identtinen Design Patterns -kirjan osoittaman kaavion kanssa (sivu 316). Kirjan vuonna -95 julkaistu painos on kestänyt hyvin ikää, ja kirjan suunnittelumallit ovat sovellettavissa kaikille oliokielille.

Alla on kaavio Strategian sovelluksesta Kirppusirkuksessa. Kantastrategia voisi olla vaikkapa tavallinenkin luokka(NullStrategy?), mutta strategian abstraktio toteutettiin pelkkänä interfacena yksinkertaisuuden vuoksi.

Lähdekoodi

Olen ParticlePanel -luokkaa tehdessäni kierrättänyt paljon kamaa omasta ohjelmoinnin harjoitustyöstäni sekä edellisen tehtävän käyttöliittymäjuttuja StarMakerista. Kämpälläni oli käytössä vain JDK 1.4.2, joten 1.5:n hienoudet jäivät hyödyntämättä -Ilkka.