02 joulukuuta, 2014

Osa 4 minimi app JavaScript

Minimi JavaScirpt -web-ohjelma (app)

Ensinnäkin mini app tarvitsee kääreen, eli kuoren tai kapselin sisuksilleen. OOP:ssä, eli objekti - orientoidussa ohjelmoinnissa on kyse juuri tästä. Valtaosa objektin älykkyydestä on piilossa paketin sisällä ja 'esiin' jää vain ohjelman hallintaan tarvittava käyttöliittymä.

Tehdään siis (triviaali) pieni objekti, jolla on yksityinen salaisuus muuttujassa ja pari funktiota joilla arvo voidaan asettaa ja lukea. Jotta tieto olisi turvassa, se pitää voida varmistaa (validate), ennen kuin se viedään perille asti. Oikea hyötyohjelma olisi paljon laajempi, mutta nyt ollaan hahmottamassa perusasioita.

var app = (function () { // app & suojattu alue alkaa
var secret,
privateSetter = function (x) {
alert( "tutkitaan:" + x);
secret = x;
return true;
}; // suojattu alue loppuu
return { // julkinen alue alkaa = interface
'get': function get () { // getter
return secret;
},
'set': function set (c){ // setter
return privateSetter (c);
}
    }; // julkinen alue loppuu
} () ) ; // app loppuu

Käydään läpi osa osalta, ulkoa sisään.

Muuttuja, jossa koko ohjelma asuu on nimeltään app.
var app = ();

Seuraavaksi on kääre -funktio. Perässään sulkeet jotka laukaisevat funktion heti.
function (){}()

Julkinen osio: return {}; Palauttaa objektin, joka sisältää pari funktiota, (aksessorit) 
getter ja setter:  function get(){}, function set(){}
Vain nämä kaksi funktiota, eli oikeastaan objektin metodia näkyvät ulospäin koko app -objektista. Kaikki muu on suojattuna (private) muuttujissa, eikä näy app -objektin ulkopuolelle. 

Getter ja setter ovat oikeutettuja (privileged) funktioita. 
Yksityinen PrivateSetter -funktio , eli metodi siirtää annetun arvon julkiselta alueelta suojatulle, varsinaiseen muuttujaan, joten tässä on sopiva tilaisuus tarkistaa syötetyn data oikeellisuus. Ei sentään ihan mitä tahansa suostuta tallentelemaan. Varsinainen validaattori tosin tästä toteutuksesta puuttuu, mutta se tulisi siis tähän kohtaan joskus lähitulevaisuudessa, sitten kun tarkemmin tiedetään millaista syötettävän datan pitäisi esimerkiksi olla
Lähiaikoina näytän täällä esimerkiksi miten arvon datatyyppi tarkistetaan.

Huomaa, että funktion palautusarvona on true. Sen voi vaihtaa tai poistaa. Voisi olla kätevää vaikkapa tietää, mikä oli muuttujan edellinen arvo, jos sen haluaa esimerkiksi perumistoimintoa (cancel) tms. varten laittaa jonnekin muistiin jne. 

Varsinainen testi alkakoon

Jos ohjelma on kasattu ja saatu selaimeen, voidaan aloittaa.
Kirjoita seuraavat testikoodit app -objektin jälkeen:

Ensimmäiset testikoodit, joilla näkee että ohjelma ehkä toimii:
app.set("Ohjelma toiminnassa!"); // tutkitaan:Ohjelma toiminnassa!

Asetetun arvon voi lukea get -funktiolla:
put(app.get()); // Message: Ohjelma toiminnassa!

Var secret on turvallinen muuttuja. Jos yrität lukea sen suoraan muuttujasta se ei onnistu.
Asetetaan ensin virallista tietä uusi arvo muuttujaan:
app.set('ABRAKADABRA'); // tutkitaan:ABRAKADABRA

Yritetään sitten saada argo ulos muuttujasta ilman getter funktiota:
alert("UGH:" + app.secret); 
// UGH:undefined - Ei onnistu ! Piilossa pysyy !

Yritetään sitten ylikirjoittaa vanhan datan päälle oikoreittiä:
app.secret = "foo"; // siitäs sait, senkin...

ja lukea se uudelleen... 
var temp = app.secret = app['secret']; // kumpi tahansa tapa käy
alert("secret:" + temp); // secret:foo 

/* Mitä, foo?! Onnistuiko ylikirjoitus?!  
Itsevarmuus kohoaa ylimitoitetuksi... Kato äiti ! */

... mutta pian:
/* Virallinen get -funktio: */
alert("app.get:"+ app.get()); 
// app.get:ABRAKADABRA   - Eiii... Minua on petetty... paha ei kannata...

Todelisuudessa kävi niin, että alkuperäisen, salaisen ja sisäisen secret -muuttujan lisäksi, lisäsit objektiin uuden this.secret -muuttujan, joka on eri alueella, kuin alkuperäinen.

Koska ne ovat eri nimiavaruudessa ne eivät oikeastaan mahda toisilleen mitään.
Ohjelman sisäiset funktion eivät yleensä yritä viitata oman objektinsa ulkopuolelle, joten sekaannuksiakaan ei pitäisi tulla. Voit tallentaa tänne vaikka puhelinnumerosi ja silti saat odottaa seuraavaa puhelua aika pitkään.

Tällainen on minimi ohjelmanen JavaScriptillä toteutettuna.
Miten sinä parantelisit sitä? Mitä puuttuu? Mitä on liikaa?