Suunnittelumallit ja kehykset
- Kurssi: Ohjelmointitekniikka:Java, kevät 2005
- Opintopiiri: Ryhmä rämä
- Opintopiirin jäsenten nimet:
- Thompson Coon, Jon
- Hela, Ilkka
- Palviainen, Markus
- Forsgren, Jukka
- Piuva, Tero
- Päiväys 4.1.2005
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:- Luontimalli (creational pattern):
Esimerkkinä Abstract factory – Malli tarjoaa liittymän, jonka avulla voidaan luoda toisiinsa liittyvien olioiden perheitä tuntematta näiden olioiden konkreettisiä perusluokkia. - Rakennemalli (Structural pattern):
Esimerkkinä Kooste – Mallin avulla voidaan olio esittää hierarkisesti toisista olioista koostuvana siten, että koosteolioita ja niiden osaolioita voidaan käsitellä samalla tavalla. - Käyttäytymismalli (Behavioral pattern):
Esimerkkinä Strategia – Malli määrittelee vaihtokelpoisen algoritmien perheen siten, että kukin algoritmi on suljettu omaan luokkaansa. Malli antaa mahdollisuuden vaihtaa dynaamisesti asiakkaan käyttämää algoritmia perheen sisällä.
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ä
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- StrategyApplet.java Pelkkä appletin kanta, irrelevantti
- ParticlePanel.java Paljon käyttöliittymäjuttua, ruudunpäivitystä ja kaksoispuskurointia
- ParticleSystem.java Käy logiikkaa läpi säikeen pyytäessä, sisältää myös particle-luokan
- Particle.java Partikkelin malli, eli "kirppu". Käsittää tyypin ja kiihtyvyyden ja katsoo ettei mene ruudun ulkopuolelle
- ParticleStrategy.java Yhteinen rajapinta eri algoritmeille
- NullStrategy.java Kirput eivät tee mitään
- ClumpStrategy.java Jengiytyvät, minimaalisella hajuraolla
- FlowerStrategy.java Lähellä -> hylkivät toisiaan. Kaukana -> vetävät toisiansa puoleensa yhä voimakkaammin.
- ChaseStrategy.java Simuloi kirppujen soidinmenoja. Värillä on väliä.
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.