Title: 582104
1582104 Ohjelmistojen mallintaminen,
suunnittelumalleja
2Suunnittelumallit (design patterns)
- Kuvaus sellaisesta luokkarakenteesta olioiden
vuorovaikutuk-sesta, joka ratkaisee tietyn
yleisen ongelman tiettyjen reunaehtojen
vallitessa - Keskeinen lähde suunnittelumalleihin Gamma et
al., Design Patterns Elements of Reusable
Object-Oriented Software, Addison-Wesley, 1995
3Ongelma kontekstissaan
- Gamma al. dokumentoivat suunnittelumallinsa
dokumentoidaan standardoidussa formaatissa - Nimi
- Ongelmakuvaus
- Ratkaisu
- Seuraukset
- Mallit ovat sidottuja johonkin ympäristöön
- Ei-olioympäristössä voisivat oliomaaliman
peruskäsitteet perintä, kapselointi ja
polymorfismi olla omia suunnittelumallejaan
4Mallien luokittelu
- Gamma et al. jaoittelevat mallinsa kolmeen
pääkategoriaan - Olioiden luontimallit (creational)
- Olioiden käyttäytymismallit (behavioral)
- Luokkien rakenteelliset mallit (structural)
- Mallien tunteminen ja käyttäminen helpottaa
kommunikaatiota suunnittelijoiden välillä - Yhteinen sanasto
- Ohjelmakoodia korkeampi abstraktion taso
5Luokkien ilmentymien luonti
- Kuka kutsuu luokan konstruktoria uuden ilmentymän
luomiseksi? - Koska ilmentymiä pitäisi luoda?
- jotkut oliot luodaan ohjelman käynnistyessä main-
tai alustusoperaatiossa - monet oliot luodaan dynaamisesti suoritusaikana,
mutta niiden luoja on tiedossa staattisesti
(käännösaikana) - joissain tapauksissa olion luoja määräytyy
dynaamisesti vasta suoritusaikana
6Luontimalli new()
- Yksinkertaisin, ja kaikkien monimutkaisempien
luontimallien hyödyntämä olion luontitapa on
käyttää kielen new-avainsanaa - new Kirahvi()
- new-avainsanaa käyttäessä kiinnitetään se
konkreettinen luokka, josta olio halutaan
instantioida - Tämä vaikeuttaa geneeristen, uudelleenkäytettävien
ohjelmien tekemistä - Luontimalleja abstrakti tehdas, rakentaja,
tehdasmetodi, prototyyppi, ainokainen
7Luontimalli tehdasmetodi (factory method)
- Määritellään luokkaan metodi, jonka tehtävä on
luoda halutunlaisia olioita. - Merkitys 1 (puhtaampi oliotapa)
- Aliluokka kiinnittää luotavan olion tyypin
syrjäyttämällä yliluokan metodin - Merkitys 2 (yleisempi)
- Metodi jollain keinoin päättää, minkä luokan olio
instantioidaan
8Esimerkki tehdasmetodista
- public static Frequency getFrequency(double d)
- Frequency f
- if(testing)
- f new MockFrequency(d)
- else
- f new ObservableFrequency(d)
-
- return f
-
9Luontimalli abstrakti tehdas
- Erilaisten, yhteenkuuluvien olioperheiden
tuottamiseksi sopii luontimalli abstrakti tehdas - Abstrakti rajapinta yhteenkuuluvien olioiden
luomiseksi kiinnittämättä niiden konkreettisia
luokkia - Mahdollistaa sovelluksen konfiguroimisen luomaan
tietyn konkreettisten aliluokkien perheen
ilmentymiä
10Abstrakti tehdas UMLnä
11Olioiden käyttäytymismallit
- Olioiden ajonaikaisen käyttäytymisen
mallintaminen - Käyttäytymismalleilla tyypillisesti pyritään
parantamaan järjestelmän joustavuutta
mahdollistamalla käyttäytymisen parametrointi
ja/tai yksityiskohtien piilottaminen - Malleja esim. vastuuketju, iteraattori, hiutale,
operaatiorunko, vierailija,.. - (Chain of responsibility, Iterator, Flyweight,
Template method, Visitor)..
12Tapahtumakäsittely
- Synkroninen kommunikointi aiheuttaa
operaatioriippuvuuksia moduulien välille - Asynkronisessa kommunikoinnissa palvelun käyttäjä
on löyhemmin sidottu palvelun tarjoajaan - Eräs asynkronisen kommunikoinnin muoto on
tapahtumaperustainen kommunikointi - voidaan toteuttaa esimerkiksi Observer-suunnittelu
mallin avulla Gamma et al., 1995 - Javassa valmis tuki rajapinnalla
java.util.Observer ja kantaluokalla
java.util.Observable
13Tapahtumankäsittelyn toteutus
- Tapahtuman lähettäjä (event originator,
publisher) - luo tyypillisesti tapahtumaolion (event object),
joka kuvaa tapahtumaan liittyvää informaatiota
(esim. ButtonEvent mikä painike) - Tapahtuman käsittelijät (event listener,
observer, subscriber) - ovat aiemmin ilmoittautuneet halukkaiksi tulemaan
informoiduksi kyseisenlaisista tapahtumista - tapahtumaolio välitetään niille kaikille
käsiteltäväksi sopivasti - Laajoissa järjestelmissä voi olla erillinen
rekisteröijä (registrator object), jolle - tapahtuman käsittelijät ilmoittautuvat ja joka
- huolehtii lähettäjien ja käsittelijöiden
välisestä kättelystä
14Tapahtumankäsittelyn aiheuttamat riippuvuudet
- Tapahtuman lähettäjä ei tiedä (eikä haluakaan
tietää), kuinka käsittelijä tulee tapahtumaan
reagoimaan - lähettäjä riippuu käsittelijästä vain hyvin
löyhästi - käytännössä se yleensä tuntee vain joukon tietyn
kuuntelijarajapinnan toteuttavia olioita - Käsittelijän ja lähettäjän välinen kättely
aiheuttaa vahvemman riippuvuuden - jos käytetään erillistä rekisteröijäoliota, se
riippuu sekä tapahtuman lähettäjästä että
käsittelijästä - jos käsittelijä rekisteröityy suoraan
lähettäjälle, se riippuu lähettäjästä - rajapintojen käytöllä voidaan löyhentää
riippuvuuksia
15Kuuntelijarajapinnan käyttäminen
tapahtumankäsittelyssä
layer control
layer
presentation
15/26
16Iteraattori
- Iteraattorilla erotellaan oliokokoelman sisäinen
rakenne ja kokoelman läpikäymisen logiikka
toisistaan - Käyttö hyvin yksinkertaista
- ListltRadiogt radios new ArrayListltRadiogt()
- .
- for(Radio r radios)
- print ( r )
-
- Iterointirajapinnan tarjoaminen ns.
asiakaspalvelua
17Operaatiorunko (template method)
- Määritellään operaatiolle yleinen runko,
yksityiskohdat vaihtelevat olioverkon
konfiguraation mukaan
18Operaatiorunko checkFrequency()
- protected boolean checkFrequency(int frequency)
- int nextStep 0
- while(nextStep lt 1000)
- if(!checkFrequency(frequency, nextStep))
- return false
-
- nextStep 25
-
- return true
-
- checkFrequency(int, int) antaa variaatiopisteen
operaatiorungolle
19Vastuuketju (chain of responsibility)
- Erotetaan palvelupyynnön lähettäjä palvelun
toteuttajasta antamalla useammalle oliolle
mahdollisuus huolehtia palvelun toteutuksesta - Toteuttaja delegoi palvelupyynnön ketjussa
seuraavalle, jos se ei itse pysty toteuttamaan
palvelua (kokonaan)
20Radiotarkistuksen vastuketju
- public boolean check()
- for(Radio radio radios)
- if(!radio.check())
- return false
-
-
- return true
21Rakennemallit
- Rakennemallit käsittelevät tapoja järjestää
luokka- ja oliorakenteita - Esim. sovitin (adapter), hiutale (flyweight),
edustaja (proxy), silta (bridge), rekursiokooste
(composition),
22Sovitin
- Olemassaolevaa luokkarakennetta
uudelleenkäytettäessä rajapinnat eivät aina ole
yhteensopivia - Sovitin-mallilla rajapintojen väliin
sijoitetaan.. sovitin
23Hiutale (flyweight)
- Hiutale-mallilla yhdistetään samanlaisia tai
samankaltaisia olioita muistin säästämiseksi - Esim. tekstinkäsittelyjärjestelmässä jokainen
yksittäinen kirjain - Sivuvaikutuksena samankaltaiset oliot voivat myös
toimia kommunikaatioyhteyksinä
24Frequency-flyweight
- public static Frequency getFrequency(double d)
- Frequency f frequencyCache.get(d)
- if(f null)
- f new MockFrequency(d)
- frequencyCache.put(d, f)
-
- return f
-
25Yhteenvetona
- Nyt läpikäytiin vain muutamia yleisesti
esiintyviä suunnittelumalleja, hyvin yleisellä
tasolla - Mallien käyttö on monesti eri mallien koostamista
ja yhteensovittamista - Esim. Flyweight Factory method