Olio- ohjelmointi ( lyhenne OOP) on ohjelmointimetodologia , joka perustuu ohjelman esittämiseen vuorovaikutteisten objektien joukkona , joista jokainen on tietyn luokan esiintymä ja luokat muodostavat periytymishierarkian [1] .
Ideologisesti OOP on ohjelmoinnin lähestymistapa tietoobjektien mallintamiseen , joka ratkaisee uudella tasolla rakenneohjelmoinnin päätehtävän : tiedon strukturoimisen ohjattavuuden näkökulmasta [2] , mikä parantaa merkittävästi mallinnusprosessin ohjattavuutta. itse, mikä puolestaan on erityisen tärkeää suuria hankkeita toteutettaessa.
Hierarkkisten järjestelmien hallittavuus edellyttää tietojen redundanssin ( normalisoinnin tapaan ) ja niiden eheyden minimoimista, joten se, mikä on luotu kätevästi hallittavaksi, on myös kätevästi ymmärrettävissä. Siten hallittavuuden taktisen tehtävän kautta strateginen tehtävä ratkaistaan - kääntää ohjelmoijan tehtävän ymmärtäminen kätevimpään muotoon myöhempää käyttöä varten.
Strukturoinnin perusperiaatteet OOP:n tapauksessa liittyvät eri näkökohtiin aiheen perusymmärryksessä, jota vastaavan mallin optimaalinen hallinta edellyttää:
Eli itse asiassa puhumme asteittaisesta tiedon järjestämisestä ensisijaisten semanttisten kriteerien mukaan: "tärkeä / ei-tärkeä", "avain / tiedot", "vanhempi / lapsi", "yksi / monikko". Erityisesti edistyminen viimeisessä vaiheessa mahdollistaa siirtymisen seuraavalle yksityiskohtatasolle, mikä sulkee kokonaisprosessin.
Tavallinen ihmiskieli kokonaisuutena heijastaa OOP:n ideologiaa alkaen esineen esityksen kapseloimisesta sen nimen muotoon ja päättyen sanan kuvaannollisessa merkityksessä käytettävän polymorfismiin, joka lopulta kehittää [ 3] esityksen ilmaisu kohteen nimen kautta täysimittaiseen käsiteluokkaan.
Datan abstraktio Abstraktio tarkoittaa merkityksellisen tiedon korostamista ja epäolennaisen tiedon jättämistä huomioimatta. OOP ottaa huomioon vain tiedon abstraktion (kutsutaan usein yksinkertaisesti "abstraktioksi"), mikä tarkoittaa joukkoa kohteen merkittävimmistä ominaisuuksista, jotka ovat muun ohjelman käytettävissä. Kapselointi [4] Kapselointi on järjestelmän ominaisuus, jonka avulla voit yhdistää luokassa dataa ja niiden kanssa toimivia menetelmiä. Jotkut kielet (kuten C++ , Java tai Ruby ) rinnastavat kapseloinnin piilottamiseen , mutta toiset ( Smalltalk , Eiffel , OCaml ) erottavat nämä kaksi toisistaan. Perintö [4] Periytys on järjestelmän ominaisuus, jonka avulla voit kuvata uuden luokan olemassa olevan luokan perusteella, jossa on osittain tai kokonaan lainattu toiminnallisuus. Luokkaa, josta perit, kutsutaan perus-, ylä- tai superluokiksi. Uusi luokka on jälkeläinen, seuraaja, alaluokka tai johdettu luokka. Alatyypin polymorfismi [4] Alatyypin polymorfismi (jota kutsutaan yksinkertaisesti "polymorfisiksi" OOP:ssa) on järjestelmän ominaisuus, joka sallii objektien käytön samalla rajapinnalla ilman tietoa objektin tyypistä ja sisäisestä rakenteesta. Toista polymorfismia - parametrista - OOP:ssa kutsutaan geneeriseksi ohjelmoimiseksi . Luokka Luokka on universaali, monimutkainen tietotyyppi , joka koostuu temaattisesti yhdistetystä joukosta "kenttiä" (alkeisempien tyyppien muuttujia) ja "menetelmiä" (funktioita näiden kenttien kanssa työskentelemiseen), eli se on tietokokonaisuusmalli, jossa on sisäiset ja ulkoiset rajapinnat oman sisällön käyttämiseen (kenttäarvot). Erityisesti luokat käyttävät laajalti yhden tai useammin kahden parillisen menetelmän erikoislohkoja, jotka vastaavat perusoperaatioista tietyllä kentällä (arvonmääritys ja lukurajapinta, getter - setter ), jotka jäljittelevät suoraa pääsyä kentälle. Näitä lohkoja kutsutaan "ominaisuuksiksi" ja ne ovat nimenomaisesti lähes identtisiä kentän kanssa (esimerkiksi kentän nimi voi alkaa pienellä kirjaimella, mutta ominaisuuden nimi voi alkaa isolla kirjaimella). Toinen ilmentymä luokan käyttöliittymäluonteesta on se, että kopioitaessa vastaavaa muuttujaa osoituksen kautta kopioidaan vain rajapinta, mutta ei itse dataa, eli luokka on referenssitietotyyppi . Tietyn luokkatyypin objektimuuttujaa kutsutaan kyseisen luokan esiintymäksi. Samanaikaisesti joissakin suoritusjärjestelmissä luokkaa voidaan esittää myös jollakin objektilla ohjelman suorituksen aikana dynaamisen tietotyypin tunnistuksen avulla . Tyypillisesti luokat suunnitellaan siten, että varmistetaan kohteen tietojen eheys sekä kätevä ja yksinkertainen käyttöliittymä, joka sopii kohteen luonteeseen ja ratkaistavaan tehtävään. Objektien ja niiden rajapintojen aihealueen eheys sekä niiden suunnittelun mukavuus puolestaan varmistetaan perinnöllä. Esine Entiteetti laskentajärjestelmän osoiteavaruudessa, joka tulee näkyviin, kun luokan esiintymä luodaan (esimerkiksi sen jälkeen, kun käännöstulokset on suoritettu ja lähdekoodi linkitetty suorittamista varten) .
Luca Cardelli ja Martin Abadi rakensivat OOP:lle teoreettisen perustelun ja luokituksen, joka perustui tähän perusteluun [5] [6] [7] [8] . He huomauttavat, että heidän tunnistamiaan käsitteitä ja luokkia ei löydy yhdessä kaikista OO-kielistä, useimmat kielet tukevat vain teorian osajoukkoja ja joskus erikoisia poikkeamia siitä.
Keskeiset käsitteet:
Luokka kuvaa abstraktia käyttäytymistä. Objektityypit rakennetaan luokan päälle lisäämällä erilaisia yksityisiä kenttiä ja menetelmiä. Rakentaja luo objektin (eli objektityypin arvon, jota kutsutaan perinteisesti "luokan esiintymäksi") alkuperäisten parametrien perusteella.
Perinteisesti luetellut OOP:n perusperiaatteet eivät vedota tähän teoreettiseen perusteluun, vaan ovat yhteisössä vakiintuneita dogmeja (joka johtaa vahvaan esitysvaihtoehtojen hajaantumiseen eri lähteissä). Suurimmaksi osaksi ne kuuluvat kieliin - Algolin ja Simulan jälkeläisiin ; vähemmässä määrin - Smalltalkin jälkeläisille (erityisesti usein mainittu Smalltalkin jälkeläisiin piiloutumisen periaate on semanttisesti saavuttamaton ja ideologisesti merkityksetön). Teoreettisesti perustuvat OOP-konseptit tukevat paljon suuremmassa määrin toiminnallisen ohjelmoinnin alalla kehittyneitä OO-kieliä : OCaml , Haskell - murteet (O'Haskell, Mondrian), seuraaja ML . Lisäksi oliomallinnuksen pääideat eivät tässä tapauksessa vaadi suoraa tukea kieleltä, vaan niitä voidaan emuloida suhteellisen helposti [9] .
Huomattavimmat erot laatuindikaattoreiden ilmenemisessä erityyppisten kielten välillä ovat:
Giuseppe Castagna [ 11] [12] [13] rakensi 1990-luvun puolivälissä yleisen perustelun dynaamiselle lähettämiselle (mukaan lukien useita ) .
OOP syntyi proseduuriohjelmoinnin ideologian kehittymisen seurauksena , jossa data ja niiden käsittelyn aliohjelmat (menettelyt, toiminnot) eivät liity muodollisesti toisiinsa. Olio-ohjelmoinnin jatkokehittämisessä tapahtuman (ns. tapahtuma-ohjelmoinnin ) ja komponentin ( komponenttiohjelmointi , COP) käsitteillä on usein suuri merkitys .
Objektit ovat vuorovaikutuksessa viestien kautta . OOP:n jatkokehityksen tulos on ilmeisesti agenttilähtöinen ohjelmointi , jossa agentit ovat itsenäisiä koodin osia ajotasolla. Agentit ovat vuorovaikutuksessa muuttamalla ympäristöä , jossa he sijaitsevat.
Kielikonstruktiot, jotka eivät liity suoraan esineisiin suunnittelultaan, mutta jotka ovat niitä mukana niiden turvallisen ( poikkeustilanteet , tarkastukset) ja tehokkaan toiminnan vuoksi, kapseloidaan niistä aspekteihin ( aspektisuuntautuneessa ohjelmoinnissa ). Olio-ohjelmointi laajentaa objektin käsitettä tarjoamalla yhtenäisemmän ja itsenäisemmän vuorovaikutuksen objektien välille. Se voi olla siirtymävaihe OOP:n ja agenttiohjelmoinnin välillä niiden itsenäisen vuorovaikutuksen kannalta.
Ensimmäinen ohjelmointikieli, joka ehdotti myöhemmin paradigmaksi kehittyneitä peruskäsitteitä, oli Simula , mutta termiä "oliosuuntautunut" ei käytetty tämän kielen käytön yhteydessä. Sen ilmestyessä vuonna 1967 siinä ehdotettiin vallankumouksellisia ideoita: esineitä, luokkia, virtuaalisia menetelmiä jne., mutta aikalaiset eivät pitäneet tätä kaikkea suurena. Itse asiassa Simula oli "Luokkien Algol", jonka ansiosta monimutkaisten käsitteiden ilmaisu proseduuriohjelmoinnissa oli helppoa. Simulan luokan käsite voidaan täysin määritellä Algol-konstruktien koostumuksen kautta (eli Simulan luokka on jotain monimutkaista, jota kuvataan primitiivien avulla).
Alan Kay ja Dan Ingalls tarjosivat ohjelmointiin "uuden näkökulman" (muu kuin menettelytapa) Smalltalk- kielellä . Tässä luokan käsitteestä on tullut perusidea kaikille muille kielikonstruktioille (eli Smalltalkin luokka on primitiivinen, jonka kautta kuvataan monimutkaisempia rakenteita). Hänestä tuli ensimmäinen laajalle levinnyt olio-ohjelmointikieli .
Tällä hetkellä olioparadigman toteuttavien sovellettavien ohjelmointikielten määrä ( kieliluettelo ) on suurin suhteessa muihin paradigmoihin. Alan yleisimmät kielet (C++, Delphi, C#, Java jne.) toteuttavat Simula-oliomallin. Esimerkkejä Smoltok-malliin perustuvista kielistä ovat Objective-C, Python, Ruby.
OOP:n keskiössä on esineen käsite . Objekti on entiteetti, jolle voidaan lähettää viestejä ja joka voi vastata niihin käyttämällä tietojaan. Objekti on luokan esiintymä. Objektin tiedot on piilotettu muulta ohjelmalta. Kapselointi sisältää piiloutumisen (mutta se ei ole!).
Kapseloinnin läsnäolo riittää ohjelmointikielen objektiivisuudelle, mutta ei vielä tarkoita sen oliosuuntausta - tämä edellyttää periytymisen läsnäoloa .
Mutta edes kapseloinnin ja periytymisen olemassaolo ei tee ohjelmointikielestä täysin oliokeskeistä OOP:n näkökulmasta. OOP:n tärkeimmät edut ilmenevät vasta, kun ohjelmointikieli toteuttaa alatyyppipolymorfismin - kykyä käsitellä eri toteutuksilla varustettuja objekteja yhtenäisellä tavalla, mikäli on olemassa yhteinen rajapinta.
OOP:lla on yli neljänkymmenen vuoden historia, mutta tästä huolimatta tälle tekniikalle ei ole vieläkään selkeää yleisesti hyväksyttyä määritelmää [14] . Ensimmäisissä objektikielissä ja -järjestelmissä määritellyt perusperiaatteet ovat kokeneet merkittävän muutoksen (tai vääristymisen) ja lisäyksen lukuisilla myöhemmillä toteutuksilla. Lisäksi noin 1980-luvun puolivälistä lähtien termi "oliokeskeinen" on tullut muotiin , minkä seurauksena sille tapahtui sama asia kuin vähän aikaisemmin termillä "rakenteellinen" (josta tuli muotia strukturoidun leviämisen jälkeen ohjelmointitekniikka ) - siitä tuli keinotekoinen "kiinni" kaikkiin uusiin kehityssuuntiin tehdäkseen niistä houkuttelevia. Björn Stroustrup kirjoitti vuonna 1988 , että oikeutus jonkin "objektiorientaatiolle" on useimmissa tapauksissa tiivistynyt väärään syllogismiin : "X on hyvä. Kohdesuuntautuminen on hyvä. Siksi X on oliosuuntautunut".
Timothy Budd kirjoittaa [15] [16] :
Roger King väitti, että hänen kissansa oli oliosuuntautunut. Muiden hyveensä lisäksi kissa käyttäytyy tyypillisesti, reagoi viesteihin, on perinnöllisillä reaktioilla ja hallitsee omaa, täysin itsenäistä sisäistä tilaansa.
Smalltalk-kielen luojan Alan Kayn mukaan , jota pidetään yhtenä OOP:n "perustajaisistä", oliolähtöinen lähestymistapa koostuu seuraavista perusperiaatteista (lainattu edellä mainitusta T. Buddin kirjasta).
Siten ohjelma on joukko objekteja, joilla on tila ja käyttäytyminen. Objektit kommunikoivat viestien kautta. Objektihierarkia rakennetaan luonnollisesti: ohjelma kokonaisuutena on objekti, joka suorittaa funktionsa, se viittaa siihen sisältyviin objekteihin, jotka puolestaan suorittavat pyydetyn viitaten ohjelman muihin objekteihin. Luonnollisesti, jotta vältytään loputtomalta toistolta puheluissa, objekti muuntaa jossain vaiheessa sille osoitetun viestin viesteiksi ohjelmointikielen ja -ympäristön tarjoamille vakiojärjestelmäobjekteille.
Järjestelmän vakaus ja hallittavuus varmistetaan objektien selkeällä vastuunjaolla (jostakin toiminnasta vastaa tietty objekti), objektien välisen vuorovaikutuksen rajapintojen yksiselitteisellä määrittelyllä sekä objektin sisäisen rakenteen täydellisellä eristämisellä. ulkoinen ympäristö (kapselointi).
OOP voidaan määritellä monilla muilla tavoilla.
Erillisen luokan käsitteen esiintyminen OOP:ssa seuraa luonnollisesti halusta saada monia samanlaisia kohteita. OOP:n luokka on ohjelmoijan luoma puhdas abstrakti tietotyyppi . Tästä näkökulmasta objektit ovat tietyn abstraktin tyypin arvoja, ja luokkamäärittely määrittää arvojen sisäisen rakenteen ja joukon toimintoja, jotka voidaan suorittaa näille arvoille. Luokkahierarkian (ja siten periytymisen) toivottavuus seuraa koodin uudelleenkäytön vaatimuksista - jos useilla luokilla on samanlainen käyttäytyminen, ei ole mitään järkeä kopioida niiden kuvausta, on parempi erottaa yhteinen osa yhteiseksi yläluokiksi, ja Jätä vain erilaisia elementtejä näiden luokkien kuvauksiin.
Tarve jakaa eri luokkiin kuuluvia objekteja, jotka pystyvät käsittelemään samantyyppisiä viestejä, edellyttää polymorfismin tukea – kykyä kirjoittaa erilaisia objekteja samantyyppisiksi muuttujiksi. Tällaisissa olosuhteissa viestin lähettävä objekti ei välttämättä tiedä tarkalleen, mihin luokkaan vastaanottaja kuuluu, ja samat viestit, jotka lähetetään samantyyppisille muuttujille, jotka sisältävät eri luokkien objekteja, aiheuttavat erilaisen reaktion.
Sanomanvaihdon käsite vaatii erillisen selityksen . Aluksi (esimerkiksi samassa Smalltalkissa ) objektien vuorovaikutus esitettiin "todellisena" sanomanvaihtona, eli erityisen viestiobjektin siirtona objektista toiseen. Tämä malli on erittäin yleinen. Se sopii erinomaisesti esimerkiksi rinnakkaislaskennan kuvaamiseen aktiivisten objektien avulla , joista jokaisella on oma suoritussäie ja jotka toimivat samanaikaisesti muiden kanssa. Tällaiset objektit voivat toimia erillisinä, täysin autonomisina laskentayksiköinä. Viestien lähettäminen ratkaisee luonnollisesti ongelman viestien käsittelystä polymorfisille muuttujille osoitetuilla objekteilla - riippumatta siitä, miten muuttuja on ilmoitettu, viesti käsittelee sen luokan koodia, johon muuttujaan määritetty objekti kuuluu. Tämä lähestymistapa on toteutettu ohjelmointikielillä Smallltalk , Ruby , Objective-C , Python .
Viestintämekanismin yleisyydellä on kuitenkin toinenkin puoli - "täysimuotoinen" viestin välittäminen vaatii lisäkustannuksia, mikä ei aina ole hyväksyttävää. Siksi monissa nykyaikaisissa olio-ohjelmointikielissä käytetään käsitettä "viestin lähettäminen menetelmäkutsuna" - objekteissa on ulkopuolelta saatavilla olevia menetelmiä, joiden kutsut varmistavat objektien vuorovaikutuksen. Tämä lähestymistapa on toteutettu valtavassa määrässä ohjelmointikieliä, mukaan lukien C++ , Object Pascal , Java , Oberon-2 . Tämä kuitenkin johtaa siihen, että viestit eivät ole enää itsenäisiä objekteja, ja sen seurauksena niillä ei ole attribuutteja, mikä rajoittaa ohjelmoinnin mahdollisuuksia. Jotkut kielet käyttävät hybridiesitystä, mikä osoittaa molempien lähestymistapojen edut samanaikaisesti - esimerkiksi CLOS , Python .
Näiden ja muiden nykyaikaisten kielten tukema virtuaalimenetelmien käsite ilmestyi keinona varmistaa, että halutut menetelmät suoritetaan käytettäessä polymorfisia muuttujia, eli pohjimmiltaan yrityksenä laajentaa kykyä kutsua menetelmiä osan toteuttamiseksi. viestinkäsittelymekanismin tarjoamista toiminnoista.
Kuten edellä mainittiin, nykyaikaisissa olio-ohjelmointikielissä jokainen objekti on arvo, joka kuuluu tiettyyn luokkaan . Luokka on ohjelmoijan ilmoittama yhdistelmätietotyyppi , joka sisältää :
Tietokentät Objektin parametrit (ei tietenkään kaikki, mutta vain välttämättömät ohjelmassa), jotka määrittävät sen tilan (aihealueen kohteen ominaisuudet). Joskus kohteen tietokenttiä kutsutaan kohteen ominaisuuksiksi, mikä voi olla hämmentävää. Itse asiassa kentät ovat arvoja (muuttujia, vakioita), jotka on ilmoitettu luokkaan kuuluviksi. menetelmät Luokkaan liittyvät menettelyt ja toiminnot. Ne määrittelevät toiminnot, jotka voidaan suorittaa tämän tyyppiselle objektille ja joita objekti itse voi suorittaa.Luokat voivat periä toisiltaan. Lapsiluokka vastaanottaa kaikki yläluokan kentät ja menetelmät, mutta voi täydentää niitä omilla tai ohittaa olemassa olevat. Useimmat ohjelmointikielet tukevat vain yhtä periytymistä (luokassa voi olla vain yksi yläluokka), vain harvat sallivat moniperinnön - luokan luomisen kahdesta tai useammasta yläluokasta. Moninkertainen periytyminen aiheuttaa useita sekä loogisia että puhtaasti toteutettavia ongelmia, joten sen täysi tuki ei ole laajalle levinnyt. Sen sijaan 1990-luvulla käyttöliittymän käsite ilmestyi, ja sitä alettiin ottaa aktiivisesti käyttöön oliopohjaisissa kielissä . Käyttöliittymä on luokka, jossa ei ole kenttiä eikä toteutusta, mukaan lukien vain menetelmäotsikot. Jos luokka perii (tai sen sanotaan toteuttavan) rajapinnan, sen on toteutettava kaikki jäsenmenetelmänsä. Liitäntöjen käyttö tarjoaa suhteellisen halvan vaihtoehdon moniperinnölle.
Objektien vuorovaikutus tapahtuu suurimmassa osassa tapauksista kutsumalla toistensa menetelmiä.
Kapselointi suoritetaan seuraavilla tavoilla:
Kulunvalvonta Koska luokkamenetelmät voivat olla sekä puhtaasti sisäisiä, jotka tarjoavat objektin toiminnan logiikan, että ulkoisia, joiden avulla objektit ovat vuorovaikutuksessa, on tarpeen varmistaa, että ensimmäiset ovat piilossa, kun taas jälkimmäiset ovat saatavilla ulkopuolelta. Tätä varten kieliin otetaan käyttöön erityisiä syntaktisia rakenteita, jotka määrittävät kunkin luokan jäsenen laajuuden. Perinteisesti nämä ovat julkisia, suojattuja ja yksityisiä muokkaajia, jotka tarkoittavat vastaavasti luokan julkisia jäseniä, luokan jäseniä, joihin on pääsy luokan sisällä ja jälkeläisluokista, ja piilotettuja, vain luokan sisällä. Muutosten erityinen nimikkeistö ja niiden tarkka merkitys vaihtelee kielittäin. Pääsymenetelmät Luokkakenttiin ei yleensä pitäisi päästä ulkopuolelta, koska tällainen pääsy mahdollistaisi objektien sisäisen tilan muuttamisen mielivaltaisesti. Siksi kentät julistetaan yleensä piilotetuiksi (tai kieli ei periaatteessa salli pääsyä luokan kenttiin ulkopuolelta), ja kenttien tietoihin päästään käsiksi erityisillä menetelmillä, joita kutsutaan accessoreiksi. Tällaiset menetelmät joko palauttavat tietyn kentän arvon tai kirjoittavat uuden arvon tähän kenttään. Kirjoittaessaan aksessori voi tarkistaa kirjoitettavan arvon oikeellisuuden ja tarvittaessa suorittaa muita käsittelyjä objektin tiedoille, jotta ne pysyvät oikein (sisäisesti johdonmukaisena). Pääsymenetelmiä kutsutaan myös accessoreiksi ( englanniksi access - access), ja erikseen - gettereiksi ( englanniksi get - get) ja settereiksi ( englanniksi set - set) [17] . Objektin ominaisuudet Pseudokentät käytettävissä lukemista ja/tai kirjoittamista varten. Ominaisuudet näyttävät kentiltä ja niitä käytetään samalla tavalla kuin käytettävissä olevia kenttiä (joitakin poikkeuksia lukuun ottamatta), mutta itse asiassa, kun niitä käytetään, aksessorimenetelmiä kutsutaan. Ominaisuuksia voidaan siis pitää "älykkäinä" tietokenttinä, jotka liittyvät objektin sisäisiin tietoihin pääsyyn muutamilla lisätoimilla (esimerkiksi kun objektin koordinaatin vaihtamiseen liittyy sen uudelleenpiirtäminen uuteen paikkaan). Ominaisuudet eivät itse asiassa ole muuta kuin syntaktista sokeria , koska ne eivät lisää uusia ominaisuuksia, vaan vain piilottavat kutsun accessor-menetelmiin. Ominaisuuksien erityinen kielitoteutus voi vaihdella. Esimerkiksi C# :ssa ominaisuusilmoitus sisältää suoraan aksessorikoodin, jota kutsutaan vain ominaisuuksien kanssa työskennellessä, eli se ei vaadi erillisiä aksessorimenetelmiä, jotka ovat käytettävissä välittömään kutsuun. Delphissä ominaisuusilmoitus sisältää vain aksessorimenetelmien nimet, jotka tulee kutsua, kun kenttää avataan. Aksessorit itsessään ovat tavallisia menetelmiä, joihin liittyy joitain lisäallekirjoitusvaatimuksia .Polymorfismi toteutetaan tuomalla kieleen sääntöjä, joiden mukaan "luokka"-tyypin muuttujalle voidaan osoittaa minkä tahansa luokkansa jälkeläisen luokan objekti.
OOP on keskittynyt suurten ohjelmistojärjestelmien kehittämiseen, joita on kehittänyt ohjelmoijatiimi (ehkä melko suuri). Koko järjestelmän suunnittelu, yksittäisten komponenttien luominen ja niiden integrointi lopputuotteeseen tehdään usein eri ihmisten toimesta, eikä ole yhtä asiantuntijaa, joka tietäisi projektista kaiken.
Oliolähtöinen suunnittelu keskittyy suunniteltavan järjestelmän rakenteen kuvaukseen (ensisijaisesti sen käyttäytymisen kuvaukseen, toisin kuin toiminnallinen ohjelmointi ), eli itse asiassa vastauksena kahteen pääkysymykseen:
Osien allokointi suoritetaan siten, että jokaisella on minimaalinen ja tarkasti määritelty joukko toimintoja (tehtäviä), ja samalla se on vuorovaikutuksessa muiden osien kanssa mahdollisimman vähän.
Lisäjalostus johtaa kuvauksen pienempien fragmenttien valintaan. Kun kuvaus on yksityiskohtainen ja vastuu määritetään, paljastuvat tallennettavat tiedot, samankaltaisten tekijöiden läsnäolo käyttäytymisessä, joista tulee ehdokkaita toteutettaviksi luokkien muodossa, joilla on yhteiset esi-isät. Komponenttien valinnan ja niiden välisten rajapintojen määrittämisen jälkeen kunkin komponentin toteutus voidaan suorittaa lähes muista riippumatta (tietysti asianmukaista teknistä kurinalaisuutta noudattaen).
Erittäin tärkeää on luokkahierarkian oikea rakentaminen. Yksi OOP-teknologialla rakennettujen suurten järjestelmien tunnetuista ongelmista on ns. perusluokan haurausongelma . Se koostuu siitä, että myöhemmissä kehitysvaiheissa, kun luokkahierarkia on rakennettu ja sen pohjalta on kehitetty suuri määrä koodia, osoittautuu vaikeaksi tai jopa mahdottomaksi tehdä muutoksia koodiin. hierarkian perusluokat (joista kaikki tai monet järjestelmässä toimivat luokat luodaan). Vaikka tekemäsi muutokset eivät vaikuttaisi perusluokan käyttöliittymään, sen käyttäytymisen muuttaminen voi vaikuttaa jälkeläisiin luokkiin arvaamattomalla tavalla. Suuren järjestelmän tapauksessa perusluokan kehittäjä ei yksinkertaisesti pysty ennustamaan muutosten seurauksia, hän ei edes tiedä, kuinka tarkalleen perusluokkaa käytetään ja mihin sen käyttäytymisen ominaisuuksiin vaikuttaa jälkeläisten luokkien oikea toiminta. riippuu.
Komponenttiohjelmointi on seuraava vaihe OOP:n kehityksessä; prototyyppi- ja luokkakeskeinen ohjelmointi ovat erilaisia lähestymistapoja yhdistettävän ohjelman luomiseen, joilla on omat etunsa ja haittansa.
Komponenttikeskeinen ohjelmointi on eräänlainen "lisäosa" OOP:n päälle, joukko sääntöjä ja rajoituksia, joiden tarkoituksena on rakentaa suuria ja pitkäikäisiä ohjelmistojärjestelmiä. Tämän menetelmän ohjelmistojärjestelmä on joukko komponentteja, joissa on hyvin määritellyt rajapinnat. Muutokset olemassa olevaan järjestelmään tehdään luomalla uusia komponentteja olemassa olevien komponenttien lisäksi tai niiden tilalle. Uusia komponentteja luotaessa aiemmin luotujen pohjalta toteutusperinnön käyttö on kielletty - uusi komponentti voi periä vain peruskomponentin rajapinnat. Tällä tavalla komponenttien ohjelmointi ohittaa perusluokan haurausongelman.
Prototyyppiohjelmointi hylkäsi luokan ja perinnön peruskäsitteet, vaikka se säilytti osan OOP:n ominaisuuksista.
Luokkakeskeinen ohjelmointi on datakeskeistä ohjelmointia, jossa data ja käyttäytyminen liittyvät erottamattomasti toisiinsa. Yhdessä data ja käyttäytyminen muodostavat luokan. Vastaavasti "luokan" 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äärittämän käyttäytymisen mukaan. Luokkasuuntautuneissa kielissä uusi ilmentymä luodaan kutsumalla luokan rakentaja (ehkä parametrijoukolla). Tuloksena olevan ilmentymän rakenne ja käyttäytyminen on luokkansa koodaama.
Grady Booch huomauttaa [18] seuraavista syistä ohjelman suorituskyvyn heikkenemiseen oliotyökalujen käytöstä:
Dynaaminen menetelmäsidonta Objektien polymorfisen käyttäytymisen varmistaminen johtaa tarpeeseen sitoa ohjelman kutsumat menetelmät (eli määrittää, mikä menetelmä kutsutaan) ei käännösvaiheessa, vaan ohjelman suorituksen aikana, mikä vie lisäaikaa. Samaan aikaan dynaamista sidontaa vaaditaan itse asiassa enintään 20 prosentissa puheluista, mutta jotkut OOP-kielet käyttävät sitä jatkuvasti. Merkittävä abstraktion syvyys OOP-kehitys johtaa usein "kerroksisten" sovellusten luomiseen, joissa objektin halutun toiminnon suorittaminen rajoittuu useisiin kutsuihin alemman tason objekteille. Tällaisessa sovelluksessa on paljon menetelmäkutsuja ja -palautuksia, mikä tietysti vaikuttaa suorituskykyyn. Perintö sumentaa koodia Periytyshierarkian "lopullisiin" luokkiin liittyvä koodi, joita ohjelma yleensä käyttää suoraan, ei sijaitse vain näissä luokissa itse, vaan myös niiden esi-isaluokissa. Samaan luokkaan kuuluvia menetelmiä kuvataan itse asiassa eri luokissa. Tämä johtaa kahteen ärsyttävään asiaan:Näistä puutteista huolimatta Booch väittää, että OOP:n käytön edut ovat suuremmat. Lisäksi suorituskykyhyöty OOP-koodin paremmasta organisoinnista, hän sanoo, joissain tapauksissa kompensoi ohjelman suorittamisesta aiheutuvia lisäkustannuksia. Voit myös huomata, että monet suorituskykyä heikentävät vaikutukset voidaan tasoittaa tai jopa poistaa kokonaan kääntäjän laadukkaan koodin optimoinnin ansiosta. Esimerkiksi edellä mainittu aksessorien käytöstä johtuva luokkakenttien käyttönopeuden hidastuminen eliminoituu, jos kääntäjä käyttää inline-korvausta aksessorin kutsumisen sijaan (nykyaikaiset kääntäjät tekevät tämän melko luottavaisesti).
OOP:n kritiikistä huolimatta tätä paradigmaa käytetään tällä hetkellä suurimmassa osassa teollisuusprojekteja. Ei kuitenkaan voida olettaa, että OOP on paras ohjelmointitekniikka kaikissa tapauksissa.
PLO:n kritiikki:
Jos yritämme luokitella OOP:n kritiikkiä, voimme korostaa useita tämän ohjelmointitavan kritiikin näkökohtia.
OOP-mainonnan kritiikki Joidenkin OOP:n propagandistien kirjoituksissa sekä "oliokeskeisten" kehitystyökalujen mainosmateriaaleissa ilmenevää tai implisiittistä käsitystä objektiohjelmoinnista jonkinlaisena kaikkivoipana lähestymistapana, joka maagisesti eliminoi ohjelmoinnin monimutkaisuuden, kritisoidaan. Kuten monet ihmiset, mukaan lukien edellä mainitut Brooks ja Dijkstra, huomauttivat, "ei ole olemassa hopealuotia" - riippumatta siitä, mitä ohjelmointiparadigmaa kehittäjä noudattaa, ei-triviaalin monimutkaisen ohjelmistojärjestelmän luominen vaatii aina merkittäviä henkisten resurssien ja ajan investointeja. OOP-alan pätevimmistä asiantuntijoista kukaan ei yleensä kiistä tämäntyyppisen kritiikin pätevyyttä. OOP-kehityksen tehokkuuden haastaminen Kriitikot kiistävät väitteen, jonka mukaan olioohjelmien kehittäminen vaatii vähemmän resursseja tai johtaa parempiin ohjelmistoihin. Kehityskustannuksia verrataan eri menetelmin, jonka perusteella päätellään, että OOP:lla ei ole etuja tähän suuntaan. Kun otetaan huomioon eri kehityssuuntausten objektiivisen vertailun äärimmäisen monimutkaisuus, tällaiset vertailut ovat vähintäänkin kyseenalaisia. Toisaalta on käynyt ilmi, että väitteet OOP:n tehokkuudesta ovat yhtä kiistanalaisia. Olio-ohjelmien suorituskyky On huomautettava, että monet OOP-teknologioiden "luonnolliset ominaisuudet" tekevät sen pohjalta rakennetuista ohjelmista teknisesti vähemmän tehokkaita verrattuna vastaaviin ei-objektiohjelmiin. Vaikka ei kiellä, että OOP-ohjelmien suorittamiseen liittyy todellakin ylimääräisiä kustannuksia (katso Suorituskyky-osio yllä), kriitikot kuitenkin liioittelevat suorituskykyä usein. Nykyaikaisissa olosuhteissa, kun tietokoneiden tekniset ominaisuudet ovat erittäin suuret ja kasvavat jatkuvasti, useimpien sovellusohjelmien tekninen tehokkuus on vähemmän merkittävää kuin toimivuus, kehitysnopeus ja ylläpidettävyys. Vain hyvin rajoitetun luokan ohjelmissa (sulautettujen järjestelmien ohjelmistot, laiteohjaimet, matalan tason järjestelmäohjelmistot, tieteelliset ohjelmistot) suorituskyky on kriittinen tekijä. Yksittäisten teknisten ratkaisujen kritiikki OOP-kielillä ja kirjastoissa Tätä kritiikkiä on lukuisia, mutta se ei vaikuta OOP:ään sinänsä, vaan sen mekanismien tiettyjen toteutusten hyväksyttävyyteen ja soveltuvuuteen erityistapauksissa. Yksi suosituimmista kritiikin kohteista on C ++ -kieli, joka on yksi yleisimmistä teollisista OOP-kielistä.Monet nykyaikaiset kielet on suunniteltu erityisesti helpottamaan olio-ohjelmointia. Voit kuitenkin soveltaa OOP-tekniikoita ei-oliosuuntautuneeseen kieleen ja päinvastoin, oliokielen käyttö ei tarkoita, että koodi muuttuu automaattisesti oliopohjaiseksi.
Tyypillisesti oliokieli (OOL) sisältää seuraavat elementit:
Jotkut kielet lisäävät tiettyjä lisäominaisuuksia määritettyyn vähimmäisjoukkoon. Heidän keskuudessaan:
Jotkut kielet noudattavat OOP:n periaatteita täysin - niissä kaikki pääelementit ovat objekteja, joilla on tila ja niihin liittyvät menetelmät. Esimerkkejä tällaisista kielistä ovat Smalltalk , Eiffel . On olemassa hybridikieliä, jotka yhdistävät objektialijärjestelmän kokonaisuudessaan muiden paradigmojen alijärjestelmiin "kaksi tai useampia kieliä yhdessä", jotka mahdollistavat objektimallien yhdistämisen muiden kanssa yhdessä ohjelmassa ja hämärtävät rajan oliosuuntautuneiden välillä. ja muut paradigmat, jotka johtuvat epätyypillisistä ominaisuuksista, jotka tasapainottavat OOP:n ja muiden paradigmojen välillä (kuten useat lähetykset , parametriset luokat, kyky manipuloida luokkamenetelmiä itsenäisinä objekteina jne.). Esimerkkejä tällaisista kielistä ovat CLOS , Dylan , OCaml , Python , Ruby , Objective-C . Yleisimmät kielet sisältävät kuitenkin objektimallien emuloinnin perinteisemmän imperatiivisen semantiikan lisäksi. Alan Kay kutsui tällaisia kieliä " ominaisuuksien agglutinaatioksi " vastakohtana tiettyä paradigmaa suoraan ilmentävien kielten " tyylien kiteytymiselle " [26] . Esimerkkejä tällaisista kielistä ovat Simula , C++ , Visual Basic , Delphi , Modula , Modula-2 , Java , C# , PHP .
![]() | ||||
---|---|---|---|---|
|
Ohjelmistokehitys | |
---|---|
Prosessi | |
Korkean tason käsitteet | |
Ohjeet |
|
Kehittämismenetelmät _ | |
Mallit |
|
Merkittäviä lukuja |
|