Liite E - Esimerkkiprojekti E Esimerkkiprojekti Olet lukenut koko kirjan. Olet sulattanut kaiken tekstin, Nyt on aika soveltaa oppimiasi uusia asioita pienen, mutta täydellisesti muotoiltuun, projektiin. Tässä liitteessä kuvaamme ongelman ja annamme joitakin vihjeitä ongelman ratkaisemiseksi. Mallivastauksen löydät Wroxin www-sivuilta. Hahmotelma Esimerkkiprojektin tarkoituksena on luoda olio-pohjainen ohjelma, joka pitää kirjaa oppilaitoksen opettajista ja oppilaista. Tämä tieto talletetaan joukkoon Opettaja - ja Oppilas -tietueita, joista molemmat sisältävät seuraavat yleiset kentät: Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit Etunimi Aakkos 20 merkkiä Sukunimi Aakkos 20 merkkiä Osoite1 Aakkos+Num. 30 merkkiä Katuosoitteen 1. rivi Osoite2 Aakkos+Num. 30 merkkiä 2.rivi Osoite3 Aakkos+Num. 30 merkkiä Viimeinen rivi Kaupunki Aakkos 20 merkkiä Maa Aakkos 3 merkkiä Postinumero Numeerinen 6 merkkiä Puhelinnumero Numeerinen 8 merkkiä Muodossa ### #### Kaikilla Oppilas-tietueilla on lisäksi seuraavat kentät: 903
C++ Ohjelmoijan käsikirja Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit OppilasID Aakkos+Num. 6 merkkiä Arvosana Numeerinen - Tulee oll välillä 0-100 Kaikilla Opettaja-tietueilla on lisäksi seuraavat kentät: Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit Opetuskokemus Numeerinen - Tulee olla positiivinen kokonaisluku (vuosissa) Palkka Numeerinen - Tulee olla positiivinen kokonaisluku 904 Ohjelman tulee olla valikko-ohjattu ja käyttäjän tulee voida suorittaa seuraavat toimenpiteet: Lisätä tietueita Poistaa tietueita Etsiä tietueita Tulostaa tietueita Poistaa kaikki tietueet Tallettaa tietueet tietokanta -tiedostoon Hakea joukko tietueita tietokanta -tiedostosta Kun tietueita lisätään, syötetyt Oppilas- ja Opettaja-tietueiden kenttien arvot tulee olla oikein syötetty. Katuosoite voi koostua korkeintaan kolmesta rivistä; jos se on alle kolme riviä, syöttö voidaan lopettaa syöttämällä riville.. Kun tietue poistetaan, käyttäjää tulee pyytää syöttämään poistettavan Opettajan tai Oppilaan sukunimi. Kun tietue on poistettu, sitä ei voi etsiä eikä tulostaa. Kun tietuetta etsitään, käyttäjää tulee pyytää syöttämään etsittävän tietueen sukunimi. Ohjelman tulee tämän jälkeen tulostaa halutun sukunimen sisältävän tietueen kaikki tiedot (eli jos tietue kuuluu oppilaalle, Arvosana ja OppilasID tulee tulostaa). Poistettua tietuetta ei voi etsiä. Kun tietueita tulostetaan, käyttäjälle annetaan seuraavat vaihtoehdot: Tulostetaan kaikki Oppilas-tietueet ja niiden kentät Tulostetaan kaikki Opettaja-tietueet ja niiden kentät Tulostetaan kaikki Opettaja- JA Oppilas-tietueet ja niiden kentät Tietueet tulee tallettaa sopivan muotoiseen tekstitiedostoon. Talletettaessa käyttäjältä tulee pyytää tiedoston nimi ja talletuksen tulee varmistaa ennen talletusta, että tämä tiedosto voidaan luoda.
Liite E - Esimerkkiprojekti Tiedostoa luettaessa käyttäjältä tulee pyytää tiedoston nimi ja ohjelman tulee varmistaa, että se voidaan avata. Tietueet luetaan tiedostosta, tarkistaa ja lisätä tietueiden joukkoon. Projektin määrittelyn parantelu Kun ongelma on nyt esitetty, huomaat varmastikin muutaman mahdollisesti epäselvän alueen: Etsimme tietueita sukunimen perusteella, joten käytämme sukunimeä hakuavaimena. Nyt saatat miettiä miten nimien duplikaatit käsitellään - jos tietokannassa on kaksi Lainetta, miten Laineen hakeminen tapahtuu? Lähes kaikilla on osoite, mutta entä jos henkilöllä ei ole puhelinnumeroa? Suunnittelijan huomiot Kun ongelma on nyt määritelty, seuraavassa on muutamia ehdotuksia, miten voimme ohjelman toteuttaa. Projektin toteutuksen suunnittelu perustuu seuraaviin yksinkertaisiin sääntöihin: Oliot pitävät huolta itsestään. Toteutetaan säiliöluokka, joka järjestelee oliot. Käytetään main()-funktiota ainoastaan yksinkertaisena liikennepoliisina. Se ohjaa ohjelman suoritusta, mutta sillä ei ole mitään vaikutusta yksittäisiin olioihin, poislukien olioiden lisääminen ja poistaminen säiliöstä. Henkilö-luokka on projektin keskipiste. Siinä toteutetaan kaikkien projektin olioiden perustoiminnallisuus. Se on muiden tämän projektin luokkien kantaluokka (eli luokkien Oppilas ja Opettaja). Kaikki tämän ohjelman oliot ovat tyyppiä Opettaja tai Oppilas ja nämä periytetyt luokat toteuttavat vain niille erikoiset toiminnallisuudet. Jokainen luokka suorittaa omat tarkistuksensa. Luokan jäsenfunktiot suunnitellaan siten, että ne tarkistavat käyttäjän syötteen, koska säännön mukaan kaikki oliot ovat itse vastuussa niiden tietosisällön oikeellisuudesta. Jos tarkistus suoritettaisiin luokan ulkopuolella, oliot olisivat jonkin ulkopuolisen olion armoilla ja koodin ylläpidettävyys tulisi hankalaksi. Myöskin olio-ohjelmoinnin perusperiaatteita rikottaisiin. Säiliö, jota käytämme Oppilas- ja Opettaja-olioille, on standardikirjaston säiliö deque. Tässä ohjelmassa emme käytä sen kaikkia ominaisuuksia, koska ainoastaan lisäämme, poistamme ja etsimme olioita. Tämä säiliö valitaan, koska sen käyttö on helppoa, mutta voisit yhtä hyvin käyttää map- tai multimap-säiliötä. Talletamme säiliöön Person*-tyyppisiä olioita, koska näin voimme polymorfismin avulla tallettaa sekä Oppilas- että Opettaja-olioita, koska ne ovat molemmat periytetty Henkilö-luokasta. 905
C++ Ohjelmoijan käsikirja Funktiolla main() ja muilla MainProg.cpp-tiedoston funktioilla on muutama velvollisuus. Ensinnäkin, main() ohjaa ohjelman suoritusta. Se kuitenkin tarkastaa käyttäjän valikkovalinnan ja se käyttää säiliöluokkaa. Funktio main() ei sisällä mitään olioihin liittyvää koodia, se vain ohjaa ohjelman suoritusta. Henkilo-luokka Henkilo-luokka sisältää periytettyjen Opiskelija- ja Opettaja-luokkien perustiedot. Se on Opiskelija- ja Opettaja-luokkien kantaluokka ja sisältää suurimman osan luokkiin liittyvästä koodista. Se on rakennettu siten, että se hyödyntää täysin jäsenmuuttujien tiedon kätkennän: Jäsenfunktio aseta() esitellään yksityiseksi, koska sitä kutsutaan ainoastaan muodostinfunktiosta. Virtuaalifunktio aseta_muu_tieto() on myöskin yksityinen, koska sitä kutsutaan periytettyjen luokkien julkisista jäsenfunktioista. Kaikki jäsenmuuttujat ovat yksityisiä, koska haluamme hyödyntää tiedon kätkennän ja sen mukanaan tuoman turvallisuuden. Periytetyt luokat Opiskelija ja Opettaja Opiskelija- ja Opettaja-luokat periytetään Henkilo-luokasta. Kumpikin sisältää tyyppinsä mukaiset jäsenmuuttujat ja jäsenfunktiot. Molemmat luokat toteuttavat myös oman versionsa virtuaalifunktiosta aseta_muu_tieto(). Säiliö Säiliö-luokka luodaan Henkilo-luokan osoittimen avulla, jotta voimme hyödyntää polymorfismin täydellisenä. Tällaisen toteutustavan vuoksi säiliö voi sisältää sekä Opiskelija- että Opettajaluokkia. Ylläpito on helppoa, koska täytyy huolehtia vain yhdestä säiliöstä. Aina kun säiliöstä tarvitaan tietue, yksinkertainen for-silmukka toimii hyvin. Seuraavat toimenpiteet ovat mahdollisia tälle säiliölle: Alkioiden lisäys Alkioiden poisto Alkioiden etsintä Lisäksi, ennen ohjelman suorituksen päättymistä säiliö tulee tyhjentää. 906
Tietojen talletus ja palautus Liite E - Esimerkkiprojekti Kun ohjelman suoritus päättyy, menetämme kaiken syöttämämme tiedon, ellemme talleta tietoja levylle. Koska emme halua liian monimutkaista ratkaisua, valitsemme yksinkertaisen tavan, jossa käyttäjä voi tallettaa tietueet tekstimuotoon tavalliseen tiedostoon. Tämä on yksinkertainen toteuttaa iostream-luokkien avulla. Lisäksi se helpottaa testausta, koska näet koko ajan, mitä tiedostoon kirjoitetaan. Voit itse valita tietueiden talletusmuodon, mutta suosittelen, että tiedoston ensimmäinen rivi sisältää jonkin erikoisrivin, josta voit varmistaa, että olet lukemassa oikean tyyppistä tiedostoa. Yhteenveto Tätä ohjelmaa voidaan parantaa monilla tavoilla, mutta se toimii hyvin perustana, johon on helppo rakentaa lisäominaisuuksia (esimerkiksi lisäämällä Rehtori-luokan). Lisäksi siinä on hyödynnetty monia C++:n ominaisuuksia. Muista myös aina, että C++-kieltä voidaan käyttää siistillä ja yksinkertaisella tavalla, mikä on koodin ylläpidettävyyden kannalta erittäin tärkeää. Kirjoita koodisi aina siten, että seuraava kehittäjä, joka lukee koodiasi on vasta-alkaja - saat tästä varmasti kiitosta pitkällä tähtäimellä! 907
908 C++ Ohjelmoijan käsikirja