- Ohj2, luennot 22-24, 6.5.-7.5.2005
- Materiaali
- Funktio-oliot ja rajapinnat
- Funktionaalisesta ohjelmoinnista
- Lisätietoa
- John Hughes: Why functional programming matters (runsaasti viitattu yleisartikkeli)
- Jared Jackson: Use recursion effectively in XSL (xslt-spesifinen, rekursioasiaa)
- Abhijit Belapurkar: Functional programming in Java language (käyttää Apachen Functor-kirjastoa, java 1.4:n takia vielä melko sotkuista)
- olion sijaan ohjelman perusyksikkö on (matemaattinen) funktio
- deklaratiivista ohjelmointia (imperatiivisen sijaan) - pyritään kuvaamaan ongelma ratkaisuaskeleiden sijaan
- ohjelma on funktio - peräkkäisyyden käsitettä ei yleensä tunneta - esim. silmukat korvattu rekursiivisilla kutsuilla
- Rekursion käyttö pienentää ohjelmakokoa, mutta on eräissä tapauksissa silmukkaa tehottomampi
- Lisäksi imperatiiviseen tyyliin tottuneelle rekursiivinen ratkaisu saattaa tuntua aluksi hankalalta (ks. esim. Hevosen Hyppely -tehtävä)
- Funktiokieliä: Haskell, Scheme, osittain myös LISP ja XSLT...
- Funktiokielet ovat yleensä sivuvaikutuksettomia: muuttujalle annettua arvoa ei voi muuttaa
- Mahdollistaa helpommin automaattisen koodin analysoinnin ja mm. oikeaksi todistamisen
- Lisätietoa esim. kurssilla Funktio-ohjelmointi
- [ http://www.mit.jyu.fi/antkaij/opetus/fo/2003/ ]
- Javan rajapinnoista ja sisäluokista yleisesti: TIJ, luku 8: Interfaces & Inner Classes
- C++:ssa mahdollista kuormittaa ()-operaattori, jolloin oliota voidaan kutsua kuin funktiota - lisäksi C++:n templatet muodostavat oman funktionaalisen kielensä C++:n sisään
- Oliota, jota voidaan kutsua kuten funktiota, kutsutaan funktoriksi
- Javassa vastaavaan toimintaan tarvitaan rajapintoja
- (huom. tässä tapauksessa rajapinnan tarkoitus poikkeaa loogisesti aiemmin käsitellystä moniperinnän välttämisestä koostamisella)
- Funktio- (tai metodi-)osoitin: keino käsitellä ohjelman _toimintaa_ kuten tietorakennetta
- Javassa korvataan "oliomaisesti" rajapinnoilla ja olioviitteillä
- Reflectionin avulla voidaan periaatteessa kutsua myös suoraan metodeja (ks. java.lang.reflect.Method), mutta tämä on hidasta
- Perinteinen käyttötarkoitus: graafiset tai menuohjatut käyttöliittymät
- Liitetään menukohtaan metodi (tapahtumankäsittelijä), jota kutsutaan, kun menukohta valitaan
- Geneeriset luokat ja nimettömät sisäluokat helpottavat funktionaalisen tyylin kirjoittamista javalla huomattavasti
- Rajapinnat tai funktio-osoittimet tukevat oliosuunnittelua - esim. erilaisten kenttien validaattorioliot
- Esim. määritellään yleinen validaattorirajapinta, josta peritään luokkia esim. henkilötunnuksen tai päivämäärän tarkistamista varten
- Esimerkit
- Ruudulle piirtämisestä
- Ks. esim. Vesterholm & Kyppö, luku 13.6: näytölle piirtäminen
- AWT vs Swing
- piirtoa varten syrjäytetään paint-metodi esim Canvas, Panel tai Applet-luokassa
- metodia kutsutaan automaattisesti, kun komponentti on piirrettävä uudelleen (tarvittaessa voidaan myös tarkistaa, mitkä ruudun osat on piirrettävä)
- Ei liian kauan kestävää koodia paintiin: ohjelman hidastuminen havaittavissa nopesti (ellei säikeitä ole käytössä, sovellus ei pysty piirtämisen aikana vastaanottamaan tapahtumia)
- Piirto"mediasta" huolimatta perusperiaate on yleensä sama: (x,y)-koordinaatisto, jonne asetetaan pikseleitä näkyviin
- Esim. demoissa piirto tekstitilaan tai ikkunaan
- KolmioPiirto, PiirtoMalli, PiirtoMalliSwing
- Päätesyöttö
- Lähtökohta: kysy_tiedot -metodin kehittäminen
- Indeksoidut kentät - keino käyttöliittymän ja sovelluslogiikan erottamiseen päätesyötössä
- Ei vaadi välttämättä omaa kenttäluokkaa - rajapinnan kannalta indeksoidut saanti- ja asetusmetodit riittävät
- Tietojen siirto näytön ja jäsenen välillä kannattaa pitää merkkijonomuotoisena (tyyppimuunnokset vain jäsenessä)
- eka: ensimmäinen _käyttäjälle näytettävä_ kenttä (id-numerot ennen ekaa)
- Toisesta tietorakenteesta haettavat valintalistat aiheuttavat hieman lisävaivaa
- toimintaa siirrettävä jäsentasolta kerhotasolle
- esim. harrastusten kysely on helppoa toteuttaa ilman lisätoimintoja (oleellisesti sama koodi kuin jäsenen tietojen kysymisessä), mutta esim. genre- tai esittäjälistan tulostaminen syötettäessä tietoja cd-rekisteriin vaatii jo pohjaa hakujärjestelmälle.
- Esimerkki:kaupunkien lisääminen jäsenrekisteriin (tietokannan normalisointia)
- Tehdään uudet luokat Kaupungit ja Kaupunki (sisältää vain nimen ja id-numeron)
- Rakenteen muutoksen seurauksena Jäsen ei enää tiedä suoraan kotikaupunkiaan, vaan ainoastaan sen ID-numeron
- Koska Jäsen ei saa olla suoraan tietoinen Kaupunki-luokasta, Jäsen ei tämän jälkeen mm. pysty tulostamaan itseään käyttäjille kaupunkitiedon kanssa => tulostustoiminto siirrettävä Kerho-luokkaan
- Lisäksi tietoja kysyttäessä käyttäjän on saatava tarvittaessa nähdä kaupunkilista, josta valita jäsenen kotipaikka => monimutkaistaa näyttöluokkaa
- Toiminta kannattaa toteuttaa täysimääräisenä vasta, kun käytössä on hakujärjestelmä - aluksi voidaan toteuttaa tietorakenne ja esim. jäsenen tulostus
- Periaate: siirretään kaupungin id-numero kenttiin, joita ei kysytä käyttäjältä silmukassa ja siirretään kysyminen suoraan näyttöön
- Käyttöliittymä esim: käyttäjä voi kirjoittaa kaupungin nimen tai pyytää listan, josta valita
- Jos kirjotettua nimeä ei löydy kaupungeista, varmistetaan kaupungin lisääminen
- Asetetaan jäsenen kapunkiID lisätyn/etsityn kaupungin ID:n mukaisesti
- Esimerkki: kerho/lukemine_71
- [ http://people.cc.jyu.fi/~minurmin/ohj2/materiaali/kerho/lukemine_71/ ]
- Harrastusten kysely? Valintalistan tulostaminen?
- Oikeellisuustarkistukset
- Vaihtoehtoja
- Omat tarkistusfunktiot kutakin kenttää varten (esim. suoraan kysy_tiedot-metodissa)
- Paljon koodia, ei ylläpidettävää
- Paluukoodin palauttaminen sijoittamisen yhteydessä
- C-tyyliä, olio-ohjelmassa ennemmin poikkeuksia käyttäen (pakottavat käsittelemään virhetilanteen)
- Yleiskäyttöisin (ja oliopohjaisin) tapa: Kenttä- ja Tarkistaja-luokat
- Esim. henkilötunnusta tarkastettaessa tarkastus tehtävä Jäsenet-luokan avulla (huom. ei ole näin kerhoesimerkissä - miten korjataan?)
- Huom. Kenttäoliotkaan eivät tiedä muista tietorakenteista, olioiden yhteistyö ylempien luokkien vastuulla
- 1-M -suhteiden tapauksessa tarvitsevat tietoa myös muista rakenteista -> tarkastus kerhossa (tai kerhoparametrilla)
- Huom. Jäsen-luokan rajapinta ulospäin pysyy edelleen samana, muutokset kysy_tiedot-metodiin minimaalisia
- Suorituskykysyistä tarkistajaoliot eivät heitä poikkeuksia, vaan virhetilanteesta ilmoitetaan merkkijonolla (null==ei virhettä)
- Esimerkit:
- Avustukset
- Yleisavustus tai sisältöriippuvainen avustus
- Avustusdatan tulee olla erillään varsinaisesta ohjelmasta
- (ohjelmoija kirjoittanee itse harvoin avustusta loppukäyttäjille - ainakaan siinä muodossa, jota loppukäyttäjä ymmärtää)
- Avustusformaatti: oma tai vaikka kokoelma HTML-sivuja
- HTML-sivut voidaan avata Javan omalla swing-selaimella tai antaa järjestelmän selaimelle (BrowserLauncher)
- HTML-sivut voidaan windowsissa koota omaksi HTMLHelp-paketiksi (chm)
- Javalla vastaava klooni: JavaHelp?
- Ali.jar-paketissa oma luokka Help avustuksia varten
- Harjoitustyöhön mielellään yksi avustuskohta/valikko (voidaan soveltaa suunnitelmasta riippuen)
- Harjoittelua avustuksen tekemiseen: ks. demotehtävä