Prototyyppiohjelmointi on olio-ohjelmoinnin tyyliä , jossa ei ole luokan käsitettä ja periytyminen tapahtuu kloonaamalla olemassa oleva objektin esiintymä - prototyyppi .
Kanoninen esimerkki prototyyppisuuntautuneesta kielestä on Self . Jatkossa tämä ohjelmointityyli alkoi saada suosiota ja oli perusta sellaisille ohjelmointikielille kuin JavaScript , Lua , Io , REBOL jne.
"luokka"-käsitteeseen perustuvilla kielillä kaikki objektit on jaettu kahteen päätyyppiin - luokkiin ja esiintymiin . Luokka määrittelee rakenteen ja toiminnallisuuden ( käyttäytymisen ), joka on sama kaikille kyseisen luokan esiintymille. Ilmentymä on tietoväline, eli sillä on tila , joka muuttuu luokan määrittelemän käyttäytymisen mukaan.
Prototyyppiohjelmoinnin kannattajat väittävät usein, että luokkapohjaiset kielet johtavat luokkien taksonomian ja niiden välisten suhteiden liialliseen painottamiseen. Sitä vastoin prototyyppien tekeminen keskittyy (pienen) määrän "kuvioiden" käyttäytymiseen, jotka sitten luokitellaan "perus"-objekteiksi ja joita käytetään muiden objektien luomiseen. Monet prototyyppilähtöiset järjestelmät tukevat prototyyppien vaihtamista ajon aikana, kun taas vain pieni osa luokkasuuntautuneista järjestelmistä (esim. Smalltalk , Ruby ) sallii luokkien dynaamisen muuttamisen.
Vaikka valtaosa prototyyppipohjaisista järjestelmistä perustuu dynaamisesti kirjoitettuihin tulkittuihin kieliin, on teknisesti mahdollista lisätä prototyyppiä myös staattisesti tyyppitarkistetuille kielille. Omega - kieli on yksi esimerkki tällaisesta järjestelmästä.
Luokkasuuntautuneissa kielissä uusi ilmentymä luodaan kutsumalla luokan rakentaja (ehkä parametrijoukolla). Tuloksena olevan ilmentymän rakenne ja käyttäytyminen on luokkansa koodaama.
Prototyyppijärjestelmät tarjoavat kaksi menetelmää uuden objektin luomiseen: olemassa olevan objektin kloonaaminen tai objektin luominen tyhjästä . Objektin luomiseksi tyhjästä ohjelmoijalla on syntaktiset keinot ominaisuuksien ja menetelmien lisäämiseksi objektiin. Tulevaisuudessa siitä voidaan saada täydellinen kopio - klooni - tuloksena olevasta objektista. Kloonausprosessin aikana kopio perii kaikki prototyyppinsä ominaisuudet, mutta siitä hetkestä lähtien siitä tulee itsenäinen ja sitä voidaan muuttaa. Joissakin toteutuksissa kopiot tallentavat viittauksia prototyyppiobjekteihin ja delegoivat osan niiden toiminnoista niille; prototyypin muuttaminen voi vaikuttaa kaikkiin sen kopioihin. Muissa toteutuksissa uudet objektit ovat täysin riippumattomia prototyypeistään. Näitä molempia tapauksia käsitellään alla.
//Esimerkki periytymisestä prototyyppiohjelmointiin //JavaScript-kielen esimerkissä //Luo uusi objekti let foo = { nimi : "foo" , yksi : 1 , kaksi : 2 }; //Toisen uuden objektin luominen let bar = { two : "two" , three : 3 }; baari . __proto__ = foo ; // foo on nyt baarin prototyyppi //Jos nyt yritämme päästä foo-kenttiin barista //se toimii bar . yksi // On yhtä kuin 1 //Muokatut kentät ovat myös käytettävissä palkki . kolme // on yhtä kuin 3 //Muokatut kentät ovat tärkeämpiä kuin prototyyppikenttien palkki . kaksi ; // On yhtä kuin "kaksi"Prototyyppisuuntautuneissa kielissä, jotka käyttävät delegointia , ajonaika pystyy lähettämään menetelmäkutsuja (tai etsimään oikeaa dataa) yksinkertaisesti seuraamalla delegointiosoittimien ketjua (objektista sen prototyyppiin), kunnes vastaavuus on tehty. Toisin kuin luokka-instanssi-suhde, prototyyppi-lapsisuhde ei vaadi jälkeläisten objektien säilyttävän rakenteellisen samankaltaisuuden prototyyppinsä kanssa. Ajan myötä ne voivat mukautua ja kehittyä, mutta prototyyppiä ei tarvitse suunnitella uudelleen. On tärkeää, että voit lisätä / poistaa / muokata paitsi dataa myös toimintoja, kun taas funktiot osoittautuvat myös ensimmäisen tason objekteiksi . Tämän seurauksena useimmat prototyyppisuuntautuneet kielet viittaavat objektin tietoihin ja menetelmiin "sloteiksi" (soluiksi).
"Puhtaassa" prototyyppityksessä – jota kutsutaan myös CSS :ksi ja joka esiteltiin Kevossa – kloonatut objektit eivät tallenna viittauksia prototyyppeihinsä. Prototyyppi kopioidaan yksitellen, kaikki menetelmät ja attribuutit, ja kopiolle annetaan uusi nimi (viite). Se muistuttaa biologisten solujen mitoosia .
Tämän lähestymistavan etujen joukossa on se, että kopion luoja voi muuttaa sen ilman pelkoa sivuvaikutuksista esi-isänsä muiden jälkeläisten keskuudessa. Myös lähettämisen laskennalliset kustannukset pienenevät huomattavasti, koska ei tarvitse käydä läpi koko mahdollisten edustajien ketjua sopivaa paikkaa (menetelmää tai attribuuttia) etsimään.
Haittoja ovat vaikeudet järjestelmän muutosten levittämisessä: prototyypin muokkaaminen ei muuta välittömästi ja automaattisesti kaikkia sen jälkeläisiä. Kevo tarjoaa kuitenkin lisäkeinoja muutosten julkaisemiseen useiden objektien välillä niiden samankaltaisuuden ("perheen samankaltaisuuden") perusteella eikä yhteisen esivanhemman olemassaolon perusteella, mikä on tyypillistä delegoiduille malleille.
Toinen haittapuoli on, että tämän mallin yksinkertaisimmat toteutukset johtavat lisääntyneeseen (delegointimalliin verrattuna) muistinkulutukseen, koska jokainen klooni sisältää kopion prototyyppitiedoistaan, kunnes sitä muutetaan. Tämä ongelma voidaan kuitenkin ratkaista optimaalisella muuttumattoman datan erottelulla ja käyttämällä Kevossa käytettyä " laiskakopiota ".
Luokkasuuntautuneiden objektimallien kannattajat, jotka arvostelevat prototyyppistä lähestymistapaa, ovat usein huolissaan samoista ongelmista, joita staattiset konekirjoittajat ovat huolissaan dynaamisesti kirjoitetuista kielistä. Keskusteluissa käydään erityisesti sellaisia aiheita kuin oikeellisuus , turvallisuus , ennustettavuus ja ohjelman tehokkuus .
Mitä tulee kolmeen ensimmäiseen kohtaan, luokkia käsitellään usein tyyppeinä (ja ne ovatkin useimmissa staattisesti kirjoitetuissa oliokielissä), ja luokkien oletetaan tarjoavan tiettyjä käytäntöjä ja taata, että esiintymät käyttäytyvät hyvin määritellyllä tavalla.
Tehokkuuden kannalta luokkien ilmoittaminen yksinkertaistaa huomattavasti kääntäjän optimointitehtävää, mikä tekee sekä menetelmistä että attribuuttien hauista instanssien tehokkaampia. Self -kielen tapauksessa suuri osa ajasta käytettiin sellaisten kokoamis- ja tulkintatekniikoiden kehittämiseen , jotka tuovat prototyyppipohjaisten järjestelmien suorituskyvyn lähemmäksi luokkakeskeisiä kilpailijoita. Jatkotyö tähän suuntaan sekä JIT-kääntäjien teorian edistyminen on johtanut siihen, että tällä hetkellä erolla luokkasuuntautuneiden ja prototyyppilähtöisten lähestymistapojen välillä on vain vähän vaikutusta tuloksena olevan koodin tehokkuuteen. Erityisesti prototyyppipohjainen Lua on yksi nopeimmin tulkitavista kielistä ja kilpailee suoraan monien koottujen kielien kanssa, [1] ja Lisaac- kielen kääntäjä tuottaa ANSI C -koodia , joka on melkein yhtä hyvä kuin natiivi. [2]
Lopuksi, ehkä yleisin kritiikki prototyyppiohjelmointia kohtaan on se, että ohjelmistokehitysyhteisö ei tunne sitä tarpeeksi JavaScriptin suosiosta ja yleisyydestä huolimatta . Lisäksi, koska prototyyppipohjaiset järjestelmät ovat suhteellisen uusia ja vielä vähän, niitä käyttävät kehitystekniikat eivät ole vielä yleistyneet.
Tietotyypit | |
---|---|
Käsittämätön | |
Numeerinen | |
Teksti | |
Viite | |
Komposiitti | |
abstrakti | |
muu | |
liittyvät aiheet |