Ugrás a fő tartalomra

Objektum orientált programozás hiba volt

Egy szakmának a tanulás és tanulmányozása általában elég sok időbe és energiába telik, mivel általánosan elmondható róluk, hogy nagyon nagy és változatos tudás bázisra épülnek, ami folyamatosan fejlődik és bővül. Pontosan emiatt nehéz róluk általánosan beszélni, de ebben a bejegyzésben mégis meg próbálom ezt megtenni.

Alapok megrepedése

  Majdnem minden mostani népszerű programozási nyelvnek az alapját az imperatív paradigma adja, ami nem meglepő hiszen annak idején nagyon fontos volt a gép közeli nyelvek használata annak érdekében, hogy minél jobb erőforrás kihasználást lehessen elérni. Viszont változnak az idők és ami régen jó megoldás volt az mára veszélyesé változott.
  Imperatív volt a legelső paradigma, amit megkérdőjeleztem, mivel van egy bizonyos tulajdonsága, ami egy olyan kétélű fegyver, ami jobban szeret minket megszúrni, mint magát a problémát. Itt side effect(vagyis mellék hatás)-ként ismert tulajdonságról beszélek. Mellék hatások abból a szempontból fontosak, hogy minden input/output esemény is annak számít.
Számomra a side effect mindig 2 dolgot jelenthetett:
  1. Egy függvény, aminek nincs visszatérési értéke(void)
  2. Egy olyan függvény, ami egy külső nem lokális és nem is konstans változó értékét használja
  Az első esett általában azért problémás, mivel a változtatásokat nem kapjuk vissza expliciten és általában a bemeneti paraméterekben kapjuk vissza a változtatásokat, ami miatt nehezebben tesztelhető lesz a függvény, hiszen a függvény helyett a bemeneti paramétereket kell majd tesztelni.
  A második eset pedig abból a szempontból problémás, hogy a függvény függ egy változótól, aminek az értéke bármikor módosulhat, ami azt jelenti, hogy a függvény függ a külső változón végrehajtott változásoktól és ami még rosszabb, hogy a függvény is módosítani tudja ezt a változót. Ebben az esetben még rosszabb a tesztelhetőség, mivel teszteléskor a külső változóra és annak értékeire is figyelni kell.
  Ennek a két esetnek a kombinációja pedig tragikusan komplex mellék hatásokat képes előidézni, ami a függvénynek a tesztelhetőségét is tragikusan megkárosítja.

  Ez a két esett elégé különbözőnek hangzik de mégis általában ugyanarra az eseményre lehet visszavezetni, ami nem más mint az értékmódosítás. Az értékmódosítás azért olyan veszélyes, mert minden mellékhatás erre az utasításra vezethető vissza. Például I/O műveletek is csak annyiból állnak, hogy a gép bizonyos regisztereinek megváltoztatjuk az értékeit.
  Értékmódosításnak még meg van az a kellemetlen hatása, hogy programunk futásába bevezeti az idő fogalmát, ami azt jelenti, hogy fontossá válik, hogy az adott változónk értéke adott pillanatban éppen menyi. Mivel ha adott pillanatban éppen rossz értéke van, akkor valószínűleg helytelen futást vagy hibát fog eredményezni. Másképpen úgy is lehet fogalmazni, hogy értékmódosítás miatt a változó egy állapot változóvá válik, ami azt jelenti, hogy ügyelnünk kell, hogy futás során mindig jó állapotba legyen ez a változónk, különben baj lesz.
Térjünk vissza az előző két esetünkhöz és képzeljük el, hogy nem engedjük meg az érték módosítást:
  1. Az első esetet úgy tudjuk megoldani, hogy a változtatásokat visszatérési értékként visszaadjuk. Ezáltal a magát a függvényt és annak visszatérési értékét tudjuk tesztelni a bemeneti paraméterek helyett.
  2. A második esetben megmarad a külső változóra való hivatkozás viszont értékmódosítás betiltása miatt ez a változó konstanssá változik. Emiatt pedig ismét könnyebben tesztelhető lesz a függvényünk, mivel nem kell a külső változó értékét változtatva tesztelgetnünk.
      Viszont ha mégis megszeretnék változtatni a külső változó értékét, akkor érdemes felvenni egy új függvényt, ami a változónak az új módosított értéket adja vissza és csak annyi a dolgunk, hogy ezt a új módosított értéket átadjuk bementi paraméterként annak a függvénynek, ami kéri a változó új értékét. Ebben az esetben két könnyen tesztelhető függvényünk lesz egy helyett.
  Egyik kellemes mellék hatása az értékmódosítás betiltásának, hogy függvényeink tiszták(pure) lesznek, amit azt jelenti, hogy bírnak  az úgynevezett referential transparency tulajdonsággal, ami azt jelenti, hogy két azonos függvény hívás mindig azonos eredményt fog eredményezni( f(a)==f(a) ).
  Ebből is látszik az imperatív és funkcionális programozás közötti különbség, míg funkcionális nyelvek a pure függvények használatát hangsúlyozzák, addig az imperatív nyelvek azok ellentétét az impure függvények használatát hangsúlyozzák.

  Másik kellemes hatása az értékmódosítás betiltásának, hogy nem alakulnak ki állapot változók, mivel minden érték változás pure függvények segítségével megy végbe, ami azért jó mert így a változások explicit módon mennek végbe függvények segítségével, vagyis egy bizonyos új érték elkészítését csak függvény hívásokkal tudjuk elérni úgy, hogy nem változtatjuk meg a változó eredeti értékét és ezáltal nem vezetünk be állapot változókat.

  Imperatív paradigma hibái ellenére mégis fontos, mivel vannak olyan algoritmusok és adatszerkezetek, amiket könnyebben lehet imperatívan megvalósítani. Nem is beszélve olyan helyzetekről, amikor nagyon fontos egy olyan gépközeli nyelv használata, amivel pontosan tudjuk irányítani a program futását és erőforrás használatát.
  Viszont az esetek többségében az ember jobban jár a funkcionális programozással vagy legalábbis funkcionális stílus használatával, mivel ebben az esetben nem csak jól tesztelhető, hanem könnyebben követhető kódot is tud készíteni az ember.

Egy ötletet imperatív alapokon

  Objektum orientáltság elég egyszerű ötletre épül: problémákat modellezzük le a való világból vett objektumok segítségével. Ezek az objektumok rendelkezzenek változókkal(állapottal) és függvényekkel(viselkedéssel). Az adott problémát ezek az objektumok oldják meg kommunikálva egymással. Objektum orientált paradigma egy nagyon könnyen vizualizálható és intuitív ötlet.
  Az összes népszerű objektum orientált nyelv imperatív alapokon nyugszik, ami azt jelenti, hogy az objektum orientált nyelvek örökölték az imperatív nyelvek erősségeit és annak gyengeségeit is egyúttal. Viszont maga az ötlet is bevezettet néhány új gyengeséget:
  1. Állapot robbanás
  2. Üzenet küldés hiánya
  3. Összetett adat szerkezet  
  Állapot robbanás: Állapot változók bevezetése exponenciálisan növeli a rendszer állapot terét.
Ez a fogalom a modell ellenőrzés világából származik és a lényege annyi, hogy minél több állapot változót használsz annál exponenciálisan nehezebben lesz érthető az egész programod működése.
Minden imperatív nyelvben gondot okoznak az állapot változóknak a száma, de egy objektum orientáltál nyelvben még súlyosabb a helyzet mivel az objektumok definíciójában benne van, hogy minden objektumnak van állapota és hogy ezek az objektumok egymással társalogva képesek egymás állapotait megváltoztatni.
 Egy objektum tehát tekinthető egy állapotnak, ami sok kis másik állapotból és olyan függvényekből áll, amik módosítgatják ezeket a kis állapotokat. Ez már egymagában komplexnek hangzik, de amikor hozzávesszük, hogy egy objektum orientált program pedig sok kis objektumból áll, amik egymással kommunikálva állandóan módosítgatják egymás állapotait, akkor rájövünk, hogy minden objektum orientált program egy hatalmas nagy és komplex állapot gépnek felel meg.
  Objektum orientáltság egyik legnagyobb hátránya, hogy ahelyett, hogy meggátolná az állapot változok keletkezését inkább ösztönzi azt.

  Üzenet küldés hiánya: Alan Kay fejéből pattant ki az objektum orientáltság ötlete, viszont elmondása szerint sokan félreértelmezték az ötletét, mivel az ötletének a lényege az üzenet küldés volt objektumok között. Üzenet küldést azért tartotta fontosnak, mivel ezáltal természetesen el tudtak szigetelődni az objektumok egymástól. Ehhez képest a legnépszerűbb OO nyelvek megengedték, hogy objektumok egymás publikus metódusait hívhassák meg, ami erőforrás hatékony módszer, viszont ezáltal az objektumok alig szigetelődtek el egymástól.
  Ez sajnos ahhoz vezet, hogy a program komponensek össze fognak fonódni, ami pedig ahhoz vezet, hogy egy komponens nagyon nehezen lesz módosítható anélkül, hogy a tőle függő komponenseket ne kéne megváltoztatni.

  Összetett adat szerkezet: Objektum az alapépítőköve minden objektum orientált nyelvnek, ami azért szerencsétlen mivel az objektumoknak nagyon komplexek. Gondoljunk bele, hogy egy objektum összeolvasztja az összetartozó adatokat, funkciókat és ennek tetejébe még örökölhetnek egymástól, tartalmazhatják egymást és meg is valósíthatnak valamilyen interfészt. Egy objektum gyakorlatilag egy imperatív programnak is megfeleltethető, mivel abban is ugyanúgy megtalálhatóak az összetartozó adatok és függvények. Csak objektumok esetében még tovább tudjuk bonyolítani a helyzetet objektum példányok készítésével és örökléssel.
  A helyzetet csak rontja, hogy új típusokat általában csak objektumok segítségével alkothatunk meg. Így még a legegyszerűbb típusaink is örökölni fogják az objektumoktól származó komplexitásokat.

Egyet előre kettőt hátra

  Sajnos az objektum orientált paradigmáról nem tudom elmondani ugyanazt mint az imperatív paradigmáról vagyis hogy fontos lenne. Azért nem tartom fontos, mivel a paradigma előnyeit elhomályosítja annak hátrányai és nem is ad túl sok pluszt az imperatív programozáshoz. Az egyetlen nagy különbség a kettő között, hogy az objektum orientált programozást "magasabb" szintű paradigmának tartják, mert egy nagyon komplex adat szerkezetet használ építő elemként. Objektumok alapként való használata nagyon jól hangzik, viszont gyakorlatban inkább ellenünk dolgozik, mint velünk.
  Én személy szerint azért nem szeretem az objektum orientált programozást, mivel nem látom, hogy lenne jövője a paradigmának és már programozás nyelvi kutatások sem foglalkoznak vele, mivel egyszerűen túl bonyolult, ahhoz hogy lehessen ráépíteni bármit is. Nem is beszélve, hogy formális verifikálásuk/model ellenőrzésüket is szinte lehetetlené teszi a paradigmánál érzékelhető súlyos állapot robbanás.

  Objektum orientáltság mindig az eszembe juttatja, hogy a választott szakmám még nagyon fiatal és még mindig abban a stádiumban van, hogy kitapogatja, hogy merre kéne haladnia. Ezért nem is meglepő ha enged a csábításnak és kipróbál egy ígéretesnek látszó ötletet, viszont fontos, hogy a hibákat felismerjük és kijavítsuk őket hiszen csak így tudjuk megtartani a helyes irányt és a profizmusunkat.
  Sokszor felteszem magamnak a kérdést, hogy mi lett volna ha annak idején nagyobb hangsúlyt kapott volna a funkcionális programozás: Szakmánk színvonala jobb vagy rosszabb lenne? Menyire lenne más az egyetemi oktatás? Milyen nyelvek lennének a legnépszerűbbek? Programok minősége javult volna? Formális verifikáció népszerűbb lenne? Esetleg minden ugyanolyan lenne csak más paradigmát használnánk? Megaynyi kérdés, amire sosem lesz konkrét válasz csak spekuláció.

Záró szavak

Remélem, hogy kellemes olvasni valónak fogja tartani ezt a bejegyzést az olvasó és nem veszi személyes támadásnak ha az esetleges kedvenc paradigmáját kritizálom. Ez a bejegyzés már egy ideje érlelődött bennem és csak most a szeretet ünnepén találtam meg a megfelelő időpontot egy ilyen komisz bejegyzés megszületésére. :D

Megjegyzések

Népszerű bejegyzések ezen a blogon

Python kezdőknek

Itt a nyár és mivel lehetne ezt a legjobban megünnepelni, mint egy kígyóról elnevezett programozási nyelv bemutatásával. Következőkben tehát a Python programozási nyelvről lesz szó és annak lehetséges alkalmazásairól.

Miért tartsunk otthon Python-t? Python pályafutása 1991-ben kezdődött el egy Guido van Rossum nevű fejlesztőnek hála, aki egy olyan általános programozási nyelvet akart készíteni, amit nagyon könnyen el lehet sajátítani és használni. Az elmúlt év tizedek alatt a Python nyelv az egyik legjobb és legnépszerűbb általános programozási nyelvé nőtte ki magát, amit bizonyít, hogy számos operációs rendszeren(linux, mac os) alapból megtalálható a nyelv. De nézzük meg, hogy mitől ilyen népszerű: Egyszerűség: A nyelvnek az egyik legnagyobb előnye, hogy nagyon egyszerű és ezért például nagyon sok egyetemen a kezdő programozó legényeket Python segítségével vezetik be a programozás világába.Dinamikus: Mint minden dinamikus nyelvnek úgy Python-nak is van egy beépített REPL-je, ami nagyo…

HTML5 játék fejlesztés alapjai

Ahogy a cím is sugallja a HTML5 játék fejlesztés alapjairól lesz szó ,hogy mi is kell hozzá.
Az én tudásom ebben a témában még elég kicsi ,de egyre növekszik ,talán egyszer majd én is össze fogok szedni annyi tapasztalatot a témából ,hogy akár még könyvet is írhatnék róla. Na persze egy izgalmas könyvet. :D

Na akkor vágjunk is bele!
    Első kérdés ,hogy mi a legalapvetőbb dolog ,amit ehhez meg kell tanulni? Persze sokan mondhatják ,hogy html , javascript ,css ismerete ,ebben igazat is adnék ,de nekünk még van ennél sokkal alapibb tudás ,ami a magyar programozókra főként igaz ez pedig az angol tudás.
Ezt nagyon sokszor tapasztalja az ember ,hogyha nem elég jó az angolja ,akkor egyetlen mondat is megtudja akasztani ,ahol az író nagyon szakmai akart lenni.
Főleg emiatt szeretem azokat az írókat ,akik semmi köntörfalazás nélkül belevágnak a lecsóban és simán és egyszerűen elmagyarázzák a dolgokat.

   Ha az első szint megvan akkor jöhet a HTML tanulása ,ami elég gyorsan letudható ,hiszen c…

Javascript kezdő lépések

Ma kis bejegyzésem arról fog szólni ,hogy mit érdemes kezdő lépésenként megtanulni ,illetve ,hogyan érdemes haladni Javascripttel és néhány érdekesség is lesz node.js-sel kapcsolatban.

Tanulás
   Szerencsére olyan világba élünk már ,ahol a web és webes technológiák nagyon gyorsan fejlődnek és ezért ezeknek a tanulása is egy fajta fejlődésen ment keresztül. Már nem könyvből kell tanulni ,hanem vannak olyan oldalak ahol interaktív módon lehet egy nyelvet megtanulni ,ami tökéletes a tanulás szempontjából. Előző cikkemben raktam be anyagokat ahhoz ,hogy mit érdemes elolvasni ,ha a tanuló inkább olvasós fajta és volt bent 2 interaktív.  Én például codecademy segítségével tanultam meg Jquery-t használni. Javascripthez Eloquent és codeacademy-t használtam.

   Mivel a Javascript elég megengedő ezért nagyon sok fajta stílusban kódolnak hozzá és ezek a stílusok  néha teljesen eltérőék. Szóval aki tanult már Java ,c vagy c++-t annak is lehet újdonság ,mivel ezeknél a nyelveknél nagyon szépen megv…