Hakemistoon

 

Yleisesti olio-ohjelmoinnista

ALIGN="CENTER">Olio-ohjelmistojen uudelleenkäytöstä

Olioparadigma tukee uudelleenkäytön ajatusta (esim. periytyminen), mutta muutakin tarvitaan.

White-box reuse eli muuntava uudelleenkäyttö tarkoittaa sitä, että aliluokka voidaan toteutaa yliluokkansa avulla. Tällöin uudelleenkäytettävä koodi on näkyvissä ja sitä voidaan muunnella aliluokassa asianomaisen operaation kohdalla.

Kompositio tarkoittaa sitä, että olioita kotaan yhteen uutta kokonaisuuta varten. Kompositio suoritetaan viiteatribuuttien (joskus myös alistettujen olioiden) avulla.

Black-box reuse eli kokoava uudelleenkäyttö tarkoittaa puolestaan kompositioon perustuvaa uudelleenkäyttöä. Koodi ei tuolloin ole näkyvissä vaan uudelleenkäyttö perustuu rajapintoihin. Voidaan sanoa tiivistetysti, että kokoava uudelleenkäyttö on "modulaarisempaa" kuin muuntava uudelleenkäyttö, jossa juuri yli- ja aliluokan likeinen suhde rikkoo ohjelmiston modulaarisuusteriaatetta, kokoava uudelleenkäyttö sisältää myös suhteessa muuntavaan uudelleenkäyttöön enemmän olioita ja vähemmän luokkia.

Delegointi tarkoittaa periytymisen toteuttamista komposition avulla. Delegointi siirtää suorituspyynnön yliluokkaoliolle mikäli ei itse voi sitä toteuttaa, atribuuttina tulee olla viite yliluokkaolioon. Ns. "tavallisessa" periytymisessähän olio käsittelee itse operaation suorituspyynnön soveltaen yliluokassa määritettyä operaatiota. Delegaation tarjoama etu on mahdollisuus muutta olion käyttäytymistä dynaamisesti. Esimerkiksi kuvioluokan olio, jonka yliluokkana on suorakulmioluokan olio, voidaan ajoaikana vaihtaa ympyrä-yliluokan ilmentymäksi. Tällainen tarve saattaisi syntyä esimerkiksi mikäli olion tehtävänä on vaikkapa pinta-alansa laskeminen ja suorakulmion sijasta on laskettava ympyrän ala koska kuvio muuttuu ajoaikana ympyräksi.

Tällaisen dynaamisen sidonnan yhteydessä operaation suorituspyynnöllä tulee olla parametrina alkuperäisen pyynnön saanut olio.

 

Sovelluskehykset

(Application frameworks)

Toisiinsa liityvien luokkien kokoelmat olioihjelmoinnissa voidaan täydentää sovelluskehyksillä toimiviksi sovelluksiksi, samassa sovelluksessa voi olla useita sovelluskehyksiä..

Uudelleenkäytetään luokkien välisen yhteistyön mallia, ei siis yksittäisiä rutiineja tai tiettyä luokkaa. Sovelluskehyksissä yhdistyvät muunnelta ja kokoava uudelleenkäyttö sekä sovelluksen kontrollin uudelleen käyttö. Sovelluskehykset voidaan jakaa kokoaviin sovelluskehyksiin, joissa korostuu kokoava uudelleenkäyttö (black-box reuse) ja muuntaviin sovelluskehyksiin (white-box reuse korostuu).

 

Kaavioesimerkki sovelluskehyksen käytöstä:

A: kontrollin siirto kehykselle, B: dynaaminen sidonta.

Sovellusohjelmoijan koodi sisältää sovelluskohtaisia aliluokkia ja sovelluskehys yleisiä käsitteitä kuvaavia luokkia. Ohjelmoija antaa joillekin kehyksen luokille aliluokkia sekä tekee alustuskoodin, joka pitää sisällään kontrollin siirron sovelluskehykselle sekä peruskomponenttien luonnin ja alustuksen. Alustuksen jälkeen kontrolli siirtyy sovelluskehykselle. Uusissa aliluokissa annattuja operaatioita kutsutaan myös myöhäisessä sidonnassa.

Tyypillinen esimerkki sovelluskehyksestä on javakielen Abstract Windowing Toolkit, AWT, jota käytetäessä jää ohjelmoijan tehtäväksi ainoastaan luoda ilmentymiä standardeille käyttöliitymäkomponenteille.

 

OMT

OMT, eli olioperustainen analyysi ja suunnittelu, käsiteltiin luennoilla ja niistä on eriillinen pieni tiivistelmä. En katsonut kuitenkaan aiheelliseksi sisällyttää tähän tiivistelmään OMT:ä koska se ei kuulu kurssin vaatimuksiin eikä sitä tulla tenteissä myöskään kysymään.

Olioparadigma

Perinteinen ohjelmistokehitys, osittava (top - down)

- askel kerrallaan tarkentuvat abstraktiotasot toiminnan karkeasta kuvauksesta aina ohjelmakoodiin saakka.

- antaa ohjelmakoodille selkeän rakenteen

- ylempien tasojen kuvauksia voidaan käyttää

suoraan ohjelmiston dokumentteina

- ohjelmistokomponentit ovat riippuvaisia ylemmän tason toiminnallisista ratkaisuista

- tietorakenteet toiminnoista irrallisia

- ei kantaa tiedon strukturointiin

Ongelmia:

- pienikin muutos ylätasolla aiheuttaa ketjureaktion ja saattaa vaatia laajaa remonttia ohjelmiin

- ohjelmistokomponenteilla huono uudelleen käytettävyysaste

- ylimmän tason mahdollinen epämääräisyys

Olioperustainen (Object-oriented) ohjelmointiparadigma:

- ohjelmiston koko elinkaaren mittainen systemaattinen prosessi

- ohjelmistot kuvataan joukkona olioita, jotka eivät ole irrallisia vaan keskenään vuorovaikutuksessa

Olioista ja oliokäsitteestä

Olio on luokan ilmentymä

Olion käsite

- strukturoinnin perusyksikkö

- ei ainoastan toiminnallinen (aliohjelma)

- ei ainoastaan tietoa säilytävä (tietue)

- kapselointi eli kotelointi on keskeinen ominaisuus

- kykenee pyydettäessä suorittamaan sille ominaiset toiminot

operaatiot

- nimi

- parametreja

- toiminnan määritely

- kykenee tallentamaan tietoa olion attribuutteihin (nimettyjä tietokenttiä)

- olion tilat ovat attribuuttien arvojen yhdistelmiä

- operaation suoritus muuttaa olion tilaa

- olion piirteet: attribuutit ja operaatiot yhdessä

- olion identifioiva tunniste on viite

- olio on suojattu, käyttö on rajattu vain tiettyihin muotoihin

Täydellisesti olioperustainen ohjelma, jos sekä kaikki sen toiminnallisuus sisältyy oioiden operaatioihin ja vastaavasti myös kaikki tieto sijoittuu oioiden atribuutteihin. Täydellisesti olioperustaisen ohjelman toiminta käynnistyy juurioliossa (root object)

Puhdas oliokieli on sellainen kieli, jolla tehdyt ohjelmat ovat aina täydellisesti olioperustaisia. Tällaisia kieliä ovat mm. Java, Smalltalk ja Eiffel.

Aktiivinen olio: edustaa omaa prosessia

Koosteolio (composite object): oliolla on osinaan toisia olioita

Oliokielistä

•Alkoivat laajemman leviämisensä ajatteluun 80-luvun puolivälissäm vaativat selvää ajattelutavan muutosta ohjelmoinnissa.

•Aiemmin mm.

- Simula (Norjan valtion laskentakeskus 60 luvulla)

- Smalltalk (70-luku ja Xerox, USA)

•Hybridikielet: ohjelmointimuokattu oliosuuntaan, ei aitoja oliokieliä.

Olioajattelun perusperiaatteet

(OhjPK/ P.Hirvonen)

- abstrahointi (abstraction)

- kapselointi eli kotelointi (encapsulation)

- tiedon suojaus (information hiding)

- periytyminen (inheritance)

- polymorfismi (polymorphism)

- dynaaminen sitominen (dynamic binding)

Oliokäsitteitä

- alistettu olio

(attribuutin arvona on kokonainen olio)

- muuttujat: nimetyt tiedon tallennuspaikat.

- viitesemantiikka (muuttujien sisältönä viitteitä olioihin)

- arvosemantiikka (arvona olio)

- kohdeolio

- väliaikainen olio

- paikallinen olio

- vapaa olio

Luokka (class)

Luokka määrittelee olioiden piirteet kertomalla mitä attribuutteja ja operaatioita luokan ilmentymällä - eli siis oliolla - on. Luokka on abstraktin tyypin muoto, olio on "käyttöön otettu luokka". Luokka määrittelee tieto- ja toiminto-osista koostuvan kokonaisuuden, jolla on oma rajapinta

Abstrakti tietotyyppi (Abstract Data Type) määrittelee käyttäjille omiin ilmentymiin sovellettavat operaatiot, mutta ei määrittele toteutustapaa eikä tietorakenteita. Abstraktin tietotyypin ilmentymän määrittelee sen tuottamat palvelut.

Abstrakti tietotyyppi esitetään käyttämällä välineitä, joilla yhteenkuuluvien määrittelyjen joukko voidaan sulkea kontrolloidun rajapinnan sisään (kapselointi eli kotelointi). Esimerkki tutusta kotelointivälineestä on on moduuli. Abstraktin tietotyypin käyttö vähentää ohjelman osien keskinäistä riippuvuutta.

Abstrakti tietotyyppi on myös lähellä olion käsitettä: "tiedon (attribuutit) ja operaatioiden (tietoon liittyvän toiminnan) kokoaminen sekä abstrahointi yhdeksi yksiköksi."

Luokka puolestaan määrittelee sekä omiin ilmentymiinsä sovelletavat operaatiot, että attribuutit.

 

 

 

Luokka on siis eräänlainen "pidemmälle viety" abstrakti tietotyyppi, joka määrittelee paitsi toiminto- niin myös tieto-osista koostuvan kokonaisuuden, jolla on oma rajapinta. Olion attribuutti on luokan attribuutin määrittelyn ilmentymä.

Luokka ei kuitenkaan ole välttämätön olio-ohjelmoinnissa, on oliopohjaisia ohjelmointikieliä (esim. Elf ja suomalainen Kevo), joissa oliot luodaan kloonaamalla ne vanhemmista olioista.

Uusi olio luodaan luontioperaatiolla, luokkaan erikoisasemassa olevalla operaatiolla, joka varaa olion attribuuteille talletuspaikan muistissa ja palauttaa arvona viitteen muistipaikkaan. Oli asetetaan usein luonnin lisäksi samalla sopivaan alkutilaan alustusoperaatiolla eli konstruktorilla asetettamalla arvot attribuuteille. Alustusoperaation voi antaa luokalle ohjelmoija, mutta tavallisesti systeemi tuottaa sen automaattisesti.

Javakielessä jokaisella luokalla on ainakin yksi oma konstruktori (alustusoperaatio) ja vapaiden olioiden luomisen on käytössä erityinen kielen operaattori (new), joka käynnistää samalla myös luokan alustusoperaation. Mikäli konstruktoria ei anneta tekee systeemi sen siis itse ilman parametreja. Konstruktorin nimi on sama kuin vastaavan luokan.

- Luokka määritellään javassa lauseella class.

- Luokan, josta luokka on periytynyt, kertoo extends.

- Luokan tyypin määrittelee muunnin (esim. public), joka usein voidaan jättää myös pois.

- Luokan mahdollinen rajapinta ilmoitetaan implements -sanalla.

Esim. Public class Demo extends Applet implements Runnable

Luokan muuntimia javassa

• Public - luokka periytyy

- muuttujia voi osoittaa kaikista muista luokista.

• Final - luokka ei periydy

- muuttujia ja funktioita voi osoittaa kaikista muista luokista

- luokan sisältöä ei voi muuttaa

• Abstract - luokasta ei voi tehdä oliota muutoin kuin periyttämällä

- luokan funktiot eivät sisällä ohjelmakoodia

• Private - luokka ei periydy

- muuttujaa voi osoittaa vain luokasta, johon se on määritelty

• Protected - muuttujaa voi osoittaa vain aliluokasta

• Threadsafe - muuttujan arvo ei vaihdu jos kaksi prosessia käyttää sitä samaan aikaan

• Synchronized - funktiota ei voi suoritaa samanaikaisesti useampi prosessi

Luokan menetelmät eli metodit

Menetelmä: "operaation toteutuskoodi", "luokan sisäinen funktio"

Esimerkki

class Luokka

{

String jono;

int luku;

void funktio (void) //<- void -funktio

{// jotain koodia//}

}

Javassa funktio ≈ metodi eli ohjelmakoodia ei ole funktion ulkopuolella

Metodit määritellään samoin kuin C-kielen funktiot

Muuttujat, jotka määritellään metodien parametrilistassa eivät voi kätkeytyä määritetyiltä muuttujilta!

Esimerkki:

class Luokka

{

String s;

int luku;

void funktio (int p{

int p; // virheilmoitus

}

}

Javassa - jokainen uusi luokka luo uuden tyypin

- jokainen uusi luokka periytyy jostain luokasta

 

Luokan käyttöönotto

(olion luominen)

• Olion määrittely:

class Olio; // vain määrittely

(luokka)

• Muisti varataan new operaattorilla:

Olio = new luokka ();

• Määrittely mikäli kyseessä on tauluko-olio:

class Olio [] = new Luokka [100]

• Kun olio on rakennettu niin sen funktiota voidaan kutsua esimerkiksi:

Funktio (1); <- sisältä

Olio.Funktio (1); <- ulkopuolelta

 

Esimerkki:

package Ihmiset;

import java.lang.String

import java.lang.System

public class Henkilo {

public Henkilo() {

}

String nimi;

int ika = 0; // attribuutti ika

void ristiminen (String n) {

nimi = new String (n); // asetetaan atribuutti nimi viittaamaan uuteen

} // String luokan olioon

void tervehdi () {

System.out.println(" Terve, olen " + nimi);

}

void vanhene () {ika++;}

}

Uusien olioiden luominen luokan pohjalta:

class J{

...

Henkilo eeva;

Henkilo aatami;

...

void kuudespaiva () {

eeva = new Henkilo();

aatami = new Henkilo ();

eeva.ristiminen ("Eeva");

aatami.ristiminen ("Aatami");

}

void aika () {

eeva.tervehdi ();

aatami.tervehdi ();

for (int vuosi = 0; vuosi <= 100000; vuosi++) {

if (vuosi < 1000) {

eeva.vanhene ();

aatami.vanhene ();

}

if (vuosi == 1000) {

eeva = null;

aatami = null;

}

}

}}

Luokan J käyttö luokan Paaohjelma operaatiossa main:

class Paaohjelma

public static void main (String args[]) {

J ruler;

ruler = new J();

ruler.kuudespaiva();

ruler.aika();

}}

 

 

 

 

 

Tietojenkäsittelytieteiden laitos, Informaatioteknologian tiedekunta, Jyväskylän yliopisto