procedurálisból OOP
Hogy tudunk átalakítani procedurálisból oop-re?Na ki hogy alakítaná az alábbi kódot oopre?
Kódot nem teszteltem csak gyorsan valamit írtam :)
■
<form>
<ul>
<li>
<input type="text" placeholder="Felhasználónév" />
</li>
<li>
<input type="password" placeholder="Jelszó" />
</li>
<li>
<input type="submit" value="Belépés" class="button" />
</li>
</ul>
</form>
<?php
session_start();
$host="localhost"; // Host név
$username=""; // Mysql felhasználónév
$password=""; // Mysql jelszó
$db_name="test"; // adazbázis név
$tbl_name="members"; // tábla név
// Csatlakozás az adatbázishoz
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
// Felhasználó és jelszó tárolás változókban
$myusername=$_POST['myusername'];
$mypassword=$_POST['mypassword'];
// Injection szürés
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);
$sql="SELECT * FROM $tbl_name WHERE username='$myusername' and password='$mypassword'";
$result=mysql_query($sql);
// Visszakérjük a sorok számát
$count=mysql_num_rows($result);
// Ha egyeznek az adatok belép és mentjük az adatokat sessionban
if($count==1){
session_register("myusername");
session_register("mypassword");
header("location:valami.php")
}
else {
echo "Hibás jelszó vagy felhasználónév.";
}
?>
Kódot nem teszteltem csak gyorsan valamit írtam :)
Procedurális?
De ő legalább escapel.
Kezdjük itt:
Semmi baj, hogy elsőre mégsem procedurális, hívhatnánk szekvenciális utasítássornak is, de nem gond, akkor első lépések:
- Nevezd nevén a fájlokat, feltételezzük, hogy van egy document-root könyvtárad, abban pedig egy private is. Majd ide tesszük, amit nem akarunk, hogy közvetlen URL-ből elérjenek (.htaccess-el most nem törődünk, feltételezzük, hogy van és műxik).
- A root-ba csak olyan fájlokat teszünk, amik publikusak, tehát működniük kell domained/fájlnév hívásra.
- Eszerint készítsd el a honlap vázát.
- Legyen egy index.php (rootban), egy private/form.htm, private/success.htm, login.php, private/config.php.
- Próbáld meg kitalálni, hogy ennyi fájlban melyik mire való. Elsőként ezekre válaszolj (próbáld meg, minden fájlra), addig ne írj kódot.
Az index.php valahogy így néz ki, de még lehet, hogy módosítani fogjuk:
Csak írd le magyarul, hogy szerinted a további fájlokban mi lesz (szépen felsorolva), és ha esetleg kihagytam valamit (simán lehet!), akkor azt is, hogy mit.
Szép lassan menjünk, lépésenként, ha már tanulunk. Egyébként nagyon profik vagyunk, mert előbb tervezünk, csak aztán kódolunk.
rendben
Egyelőre csináld meg
+1
Kaptam egy Macbookot fatertól :D
Ez brutál
Na de kezdodjon a php
És most hol tartunk?
Itt a GitHub-ra én -1-elek.
Kicsike kódok lesznek, simán elfér itt, és maradjunk a lépéseknél, ha már leírtam. Ne kezeljük rögtön úgy, hogy "szórj össze valamit, majd optimalizáljuk".
Ő most megérteni szeretné és megtanulni, arra rossz módszer az (és sok másra is), hogy csinálj gyorsan valamit rosszul, aztán majd javítgatjuk.
Igen javaslom, hogy maradjunk itt, és az általam írt sorrenben-sebességgel. Ha többen többfelé rángatjuk, csak káosz lesz belőle, akkor én inkább kimaradok. Nem értem, mi rossz van abban, amit indítványoztam. Pont az a lényeg, hogy lépésről-lépésre tanuljon, ne ide-oda kapkodva.
Ez nem egy határidős projekt, ne keverjük össze!
Egy gist olvashatóbb is, meg
Ami nagyobb probléma, hogy az OOP a nagyobb komplexitás kezelésére lett kifejlesztve. Ha annyi egy feladat, hogy ellenőrizzük le, hogy egy form mező értéke szerepel egy adatbázisban, arra a fenti még-csak-nem-is-procedurális kód nagyjából adekvát megoldás. Neház úgy megérteni valamit, ha olyan példákon mutatják be, amiken semmi haszna nincsen.
+1, -1
Lépésenként gondolok menni procedurálisba, onnét OO. Akkor fogja megérteni szerintem, legalábbis a nagyon alapokat. Interface-t nem is tervezek, max. egy öröklődés a végére (mondjuk akkor kellhet), de csak kis lépésekben akarom bonyolítani, a mélyvíz erre tuti nem jó. Aztán szóltok, ha valamit elrontok...
Tőlem mehet akárhova, én leírtam, miért (kikért) hagynám itt. Itt akárhány tanulónak szólhat, ott kb. egynek (utólag nemigazán értik a később jövők, általában nem profi Git-felhasználók, egyébként én sem, úgyhogy ha oda megy, továbbképzés kell :)). Azért nem mindegy, ha sok időt töltök vele.
Az ilyen példák általában úgy
"Bizonyos komplexitás"
Nekem egyfajta dogmatikus paradigmaváltásnak tűnik az OOP, és nem láttam még úgy megközelítve, hogy „ez a kód így procedurálisan jó, de a felhasználókat célszerűbb lenne objektumként kezelni”. Inkább az érződik, hogy „na, innentől akkor minden objektum”. Nem értem, hogy ha szeretnék például kiíratni egy műveletről értesítést a felhasználónak, akkor egy
result(0,'Hiba!')
ill.result(1,'Siker!')
jellegű függvények helyett miért kellene$result->setType(0);
$result->setText('Hiba!');
$result->render();
módon elérnem ezt. Még akkor sem, ha tudom, hogy
(new Result(0,'Hiba'))->render()
módszerrel is megoldható a PHP 5.4 óta. Vagy ha a render() metódus benne van a konstruktorban, és esetleg lenne egy Error osztályom, ami a Resultból öröklődik, akkor se a típus megadása, se a renderelés explicit meghívása nem kell, csak egynew Error('Hiba')
. És persze ezt a fajta öröklődést eljátszhatom procedurálisan is, ha azerror($msg)
meghívja aresult($type,$msg)
függvényt a szükséges első paraméterrel.Őszintén örülök, hogy elindul egy ilyen kezdeményezés az OOP-re való áttérés gyakorlati bemutatásáért – szerintem van miről beszélni.
És mi ez a bizonyos
Ha elvont a problémád: magas absztrakciós szintű, akkor elég egyértelmű, hogy magas absztrakciós szintű eszközöket érdemes használnod: objektum orientált megközelítést. Ha nagyon konkrét a problémád: alacsony absztrakciós szintű, akkor el kell gondolkodni azon, hogy tényleg annyira konkrét e, és ha igen, akkor érdemes alacsony absztrakciós szintű eszközöket használnod: procedurális megközelítést.
Ha rugalmas, cserélhető, könnyen karbantartható kód kell, akkor olyat oo-ban könnyebben lehet írni, mint procedurálisan, mert vannak direkt ilyen célra kitalált eszközök. Ha procedurálisan akarsz könnyen karbantartható kódot készíteni, akkor arra is lehetőséged van, csak ezeket az eszközöket újra fel kell találnod hozzá, ami meg úgy általában időpazarlás, mert már más megcsinálta helyetted sokkal jobban. Szerintem az esetek 99.9%-ában érdemes oo nekikezdeni a problémának. A maradék 0.1% az, aki alacsony szintű dolgokat ír, vér profi, és pontosan tudja, hogy mit csinál. Bármennyire is szeretnéd, nem tartozol ebbe a kategóriába, különben nem ezt a fórumot olvasnád... :-)
Az alábbi kódok tartalom
A.)
B.)
'type' => 0,
'text' => 'Hiba!'
));
C.)
setType($result, 0);
setText($result, 'Hiba!');
render($result);
D.)
$result->setType(0);
$result->setText('Hiba!');
$result->render();
E.) - fiktív tgr kedvéért (utólag hozzászerkesztve)
$type = 0,
$text = 'Hiba!'
);
Szerinted melyik a legkönnyebben olvasható, módosítható, karbantartható?
Ennek mondjuk nincs köze az
A kód olvashatósága akkor is
A kód olvashatósága akkor is rosszabb lesz, maximum ha eltördelik paraméterek szerint külön sorba, meg a result-nak külön névteret adnak, akkor talán kevésbé.
Imho mindent meg lehet csinálni procedurálisan is amit oo-ban, csak jóval körülményesebb, legalábbis eddig ahányszor próbáltam, nem tudtam olyan példát felhozni, ami oo-ban ment, és procedurálisan nem...
Tényleg csak az eszközök kidolgozottságában van különbség. Szerintem az osztály egy absztrakció, amit ismétlődő procedurális kódminták alapján találtak ki. Kb olyan, mint oo-ban a programtervezési minták. Nyilván valamelyest szűkíti az elérhető lehetőségek körét, de mint best practice cserébe elég sokat ad. Ugyanez a helyzet a tervezési mintákkal is és a solid elvekkel is. Ha már itt tartunk, akkor ugyanez a helyzet a nevesített paraméterekkel is... :-)
Szerintem az oo használata mellett a fő szempont a kód olvashatósága, karbantarthatósága, a közös nevezéktan egyes mintákra, amit osztály nevekben is jelölni lehet, plusz néhány mankó, ami az osztályok sajátsága: adatrejtés, polimorfizmus, interface-ek, stb... Szóval egyértelműen az oo-val kapcsolatos beépített eszközök, amiben többet nyújt a procedurálisnál, minden más pedig a programozón múlik. Ha nem használja ezeket a beépített eszközöket, vagy nem megfelelően használja, akkor simán lehet rosszabb minőségű a kódja, mint egy procedurálisan írt kód. Szóval az oo megközelítés egy eszköztár, ami szakértelmet igényel, cserébe - megfelelően használva - megkönnyíti a munkát, ugyanúgy mint minden eszköz.
+1
Igen, egy szerszámkészlet, a tervezett csobogódat is összehozod egy csavarhúzóval, egy kombifogóval és némi cikkcalaggal, vagy felszereled magad rendesen: blankolófogó, saruzófogó, érhüvelyező, forrasztópáka, .......
Remélem neked többet is elmond a példám. :)
Szerk.: én továbbra is várom a kérdező megnyilvánulását: most megyünk arra, amerre javasoltam, vagy nem? Vitatkozni nem akarok többet róla, mindenki másképp látja a világot. Azért is találtam ezt ki, mert hátha még valaki meglátja benne a "tetszetős" momentumokat (nem mondom meg ki, de konkrét személyre gondolok).
Szerintem az oo használata
Mi szükség van erre?
Ha kétségeid vannak, nyiss neki egy témát, hozz egy gyakorlati példát (de lehetőleg ne olyat, mint múlt héten, amiről messziről látszott, hogy mit akarsz belőle kihozni), és megbeszéljük. De ezek a tényeket nélkülöző, levegőbe puffogtatott demagóg állítások egy olyan topicban, ahol valaki az OOP tanulásában kér segítséget, nem épp szerencsések, sőt.
Fordítsuk meg: miért kell
A téma nyitója azért kér ebben segítséget, mert múltkor meg lett neki mondva, hogy OOP-t kell tanulnia. Neki fogalma sincs arról, hogy valójában erre van-e szüksége, valamint itt már tgr is megkérdőjelezte, hogy a felhozott példában van-e értelme bármit is objektumokkal machinálni.
Igazad van, ideje most már összeszedni egy helyen a tényeket, és be kéne mutatni az alternatívákat, mert vannak más utak is.
Fordítsuk meg: miért kell
Megcáfolni nem cáfolták. Vannak kritikusai, mint mindennek, és legtöbben az overengineeringet hozzák fel ellenpéldának, nem a paradigma értelmetlenségét.
Ha valaki programozóként akar dolgozni jelenleg, akkor az OOP-t meg KELL tanulni, ugyanis egy szint fölött minden normális helyen elvárás a gyakorlati alkalmazási tapasztalat. Én legalábbis eddigi pályám során még sehol nem találkoztam vele, ahol ez ne így lenne.
Azt kérdőjelezte meg, hogy miért ilyen példával kell bemutatni az OOP-t... És ebben egyet is értek vele. Nem értem ez mit cáfol. Nyilván verébre nem lövünk ágyúval, mert értelmetlen, és ki se derül belőle, hogy az ágyú mire jó.
Nyilvánvalóan vannak alternatívák. A kérdés az, hogy melyik feladatra mi a jobb, hogy egy minimálisnál nagyobb komplexitású és több éves fejlesztési és karbantartási periódusú project során melyik paradigmával lehet hatékonyabban dolgozni (olvashatóság, karbantarthatóság stb). Én abban kételkedek, hogy egy tényfelsorolással ezt, vagy azt alá lehet támasztani, de a kedvedet nem akarom elvenni tőle. Ahogy tgr hivatkozott hozzászólása is rámutat, ezt értelmes gyakorlati példákon, tapasztalattal lehet felmérni és megérteni.
miért kell mindig állítani
Ilyennel még nem találkoztam, mutass egy ilyen cáfolatot!
Az olvashatóság teljesen
Az olvashatóság egyáltalán
nézz meg egy obfuszkált meg
És ebből mi fog kiderülni?
Hogy az obfuszkált
Egy futtatókörnyezetnek
A futtatókörnyezetet
Mérhető?
Odaállítasz ezer embert két
Szubjektum
$valtozo = boolean ? 'igaz' : 'nem igaz';
sor is, és egy középhaladónak sem fog feltétlenül elsőre egyértelmű lenni a DIC-ek használata. Ugyancsak nem mindenkinek segíti az olvashatóságot, ha apró függvényekre bontod a kódot (akár több fájlban), más pedig a hosszú metódusokat nem tudja átlátni. A változók és függvények, táblák és mezők elnevezése is valakinek így jó (pl. $objlat), míg másoknak amúgy (pl. $objektum_lathatosaga vagy $object_visibility).Az olvashatóság nem a
Más szinteken már szubjektívvé válhat, egy zseni olyan kódot is könnyen olvas, amit én egyáltalán nem.
Az első cikk valakinek a
A második cikk arról szól, hogy nem növeli a produktivitást az oop. A karbantarthatóságról szó sincs benne, a LOC-ot használ a produktivitás mérésére, és az elején leírják, hogy a LOC a karbantarthatóságot nem veszi figyelembe. A karbantarthatóság erősen függ a kód olvashatóságától, ami meg, mint már fentebb írtam erősen nyelv függő, hogy oo-ban lehet e jobban olvasható kódot írni, vagy csak pont ugyanannyira olvashatót, mint procedurálisan.
Összefoglalva az oo-val olvashatóbb, vagy pont annyira olvasható kódot lehet írni, mint procedurálisan, és mindez programnyelv függő. Abban az esetben, ha olvashatóbb a kód, akkor könnyebben karbantartható.
Hibakezelés A kivételkezelés
A kivételkezelés nem egy olyan nagyon különleges dolog, amit ne lehetne procedurálisan megcsinálni: egy speciális objektumot ad vissza, aminek van pár beépített változója és metódusa.
...
throw new SomeException();
}
try {
$eredmeny = this->metodus();
}
cache (SomeException $e) {
print $e->getMessage();
}
catche (Exception $e) {
throw $e;
}
$this->kovetkezo_metodus($eredmeny);
Ezt a működést a következőképp lehet utánozni:
...
return array(
'hibakod' => SOMEHIBA
);
}
$eredmeny = fuggveny();
if ($eredmeny['hibakod']) {
if ($eredmeny['hibakod'] === SOMEHIBA) {
print hibakezelo($eredmeny);
}
else {
return $eredmeny;
}
}
kovetkezo_fuggveny($eredmeny['ertek']);
Tehát a függvényünk nem közvetlenül egy eredményt ad vissza, hanem egy indexelt tömböt, amiben szerepel a hibakód, az esetleges behelyettesítendő paraméterek, ezek akkor, ha hiba történt, különben pedig hibakódként egy 0, valamint az eredmény.
A két kód ekvivalens, mert bizonyos esetben maga az aktuális függvény kiprinteli a hibaüzenetet, ha más típusú, általános hiba történt, akkor pedig továbbadja a szülőjének, ahol lekezelhetjük ezt.
Olvashatóság, karbantarthatóság
Az olvashatóságot továbbra is szubjektívnek tartom. Az első cikkben pont arra próbáltam rámutatni, hogy csupán az OOP-től nem lesz olvashatóbb a kód, ott is csak azon múlik, aki írta. Az olvashatóságnál valóban az a fontos, amire BlaZe utal, hogy más számára is az legyen, ezt pedig bármilyen programozási paradigma mellett el lehet érni, ha van egy szabályrendszer, amit mindenki betart.
HibakezelésA kivételkezelés
Hát ez a lehető legrosszabb módja a try-catch utánzásának, ugyanis az több szint mélységből jövő hibákat is elfog. A te módszerednél minden egyes szintnél ugyanazok az if-else ágak ismétlődnének, és egy magasabb szinten mindent elborítana a hibakezelés miatti zaj. A PHP-ben van hasonló nyelvi elem hibakezelésre, azt kell használni:
Bizonyos nyelveknél van hasonló procedurális nyelvi elem, mint a try-catch:
Pl/PgSQL
Ez így van, procedurálisan is lehet olvasható kódot írni, itt is nyelvi eszközök kérdése az egész, ha szét lehet szedni a függvényeket névterekbe, és van hasonló nyelvi elem, mint a use a php-ban, amivel nem kell állandóan kiírni, hogy melyik függvény melyik névtérből van, akkor lehet ugyanolyan olvasható kódot írni procedurálisan is, mint oo-val. Ellenkező esetben nem. Gyanítom, hogy kevés az olyan nyelv, ahol ez támogatott.
Ha az adott nyelvet direkt felkészítették arra, hogy procedurálisan is el lehessen érni ugyanazokat az eszközöket, mint amiket objektum-orientáltan általában lehet, akkor procedurálisan is lehet olyan minőségű kódot írni, mint objektum-orientáltan. Ha viszont nem készítették fel erre, akkor objektum-orientáltan jobb kód minőség érhető el, bármennyire is erőlködik az ember procedurálisan. A PHP esetében a procedurális programozás kevésbé támogatott, mint az objektum orientált, így annak az esetében jobb választás objektum-orientáltan programozni. A javascript-re, java-ra ugyanez igaz. A Pl/PgSQL-re viszont ugyanez már nem igaz. Lehetne csinálni egy táblázatot az egyes nyelvekről ezzel kapcsolatban...
Hát ez a lehető legrosszabb
Szerintem jóval egyszerűbb
Valóban egyszerűbb, de a
– Verity Stob
Jelenleg ez az egyetlen
Mivel a szabványos könyvtárak
IOException
), úgysem tudsz áttérni. Én is együttélek velük, csak ne higgyük azt, hogy ez a jó megközelítés.Jó, de tegyük fel, hogy
Vannak wildcard visszatérő értékek, amik garantált, hogy kód duplikációhoz, és átláthatatlan kódhoz vezetnének.
Vannak kivételek, amik ha kezeletlenül maradnak, akkor a felhasználó csak pislog, hogy mivan.
Több lehetőséget nem látok...
Wildcard alatt nem tudom, mit
A wildcard alatt azt értem,
A mostani kivétel kezelés miben más? Ha beteszem egy try-catch blokkba, akkor ugyanúgy goto, és meghatározott helyre ugrik...
A mostani kivételkezelés
Közben rájöttem, hogy
Ez az egyik része. A másik
Közben megnéztem a go-t, a
Az szerintem nem baj, hogy nem kényszerít rá a kivétel elkapásra. Azt szeretem én tudni, hogy hol akarom elkapni... Nyilván amin azt szeretném, hogy semmi ne menjen át, oda kiteszek egy catch Throwable-t, vagy go esetében üres interface-t fogok el, stb...
Közben megnéztem a go-t, a
Ilyen pl javaban is van, végre. Már úgy értem, ami a try-catch végén felszabadítja az erőforrásokat. A finally ágban close-okkal szüttyögés eléggé határeset volt nagyüzemben :)
Pedig van, ahol ez jobb megfordítva, mármint hogy rákényszerít, hogy kapd el, max te továbbdobhatod, ha úgy látod jobbnak. Viszont explicit módon lekezelteti veled a hibát, az nem csapódhat bele váratlanul a szál tetejébe, vagy valahová egy jóval magasabb absztrakciós szinten, ahol nincs mód érdemben lekezelni a hibát. Javaban erre vannak a checked exceptionök. Erről ugye van vita, hogy jó, vagy sem. Szerintem speciel hasznos, lásd pl InterruptedException, vagy egyéb olyan exceptionök, amiket le KELL kezelnie a hívónak.
Nekem azért nem tetszik, mert
Sztringet konvertálsz
Ez mind szituáció függő. Pl
A kivételkezelést akkor
Az egyedüli eszköz, aminek
Az Ada 1977-ben elsők közt vezette be a ma ismert kivételkezelést, hosszú-hosszú évekkel korábban, mint a polimorfizmust. Most akkor a kivételkezelés nem objektumorientált gyakorlat? Vagy a polimorfizmus nem szükséges feltétele az objektumorientáltságnak?
Mikor látjátok már be – és ez a válasz kifejezetten Gábornak is szól –, hogy semmi kézzelfoghatóról nem beszéltek? Típusosság, névterek, adatrejtés, interfészek, öröklődés, polimorfizmus, kivételkezelés: ezekről van értelme vitatkozni. Objektumorientáltságról és arról, hogy egy függvény argumentumát a függvény neve elé vagy mögé írjuk, nincs.
Így igaz
Gábor, még nem láttam összeszedettebb procedurális kódodat, de majdnem a nyakam merném tenni rá, hogy akár ráfogható OO szemlélet. És erről vitázunk...
Igazad van, Ádám: ez így hülyeség. (Bocsánat! Szakmailag helytelent akartam mondani. :))
Pedig elég egyszerű
Amúgy a tipikus oo eszközök mindegyike kiváltható procedurálisan is valami hasonlóval, ez tényleg csak attól függ, hogy mennyire támogatja az ilyesmit az adott programnyelv. Pl adatrejtést closure-al, try-catch-et egy hasonló nyelvi elemmel, objektumokat olyan adatstruktúrával, amire closure-okat szórsz fel, és így tovább...
Mi az az objektum?
Kb adat és függvények
pl:
Ezzel akkor azt mondod, hogy
Talán azért, mert ezt végig
Van, akinek a procedurális programozásnál érvényes elvek sem tiszták, pl hogy miért fontos a kód újrahasznosítás vagy a kód olvashatósága... Hajlamosak ezeket az elveket, meg még egy csomó mást összemosni az objektum orientáltsággal. Az objektum orientáltság minden tulajdonsága teljes egészében következik a procedurális programozásból az encapsulation megkötésével.
Van más különbség is az oo
Szóval az objektum orientált programozást az különbözteti meg a procedurálistól, hogy van plusz egy megkötése: az egységbe zárás (encapsulation), az oo megközelítés minden egyéb jellemzője levezethető ebből. A procedurális elvek egy az egyben átemelhetőek oo-ra: kód újrahasznosítás, olvashatóság, stb... Ezek az encapsulation-el együtt a SOLID eleveket kényszerítik ki. A SOLID elvekből meg további elvek következnek. Egyelőre még jobban összeszedem a témát, aztán valamikor a télen írok cikket erről.
A procedurálisnál a
Száz szónak is egy a vége: ha feszegetjük, akkor mindig oda fogunk kilyukadni, hogy az obejtumorientáltság polimorfizmus. Minden más létezett már korábban is.
Száz szónak is egy a vége: ha
Ezen az alapon azért a strukturált programozás se volt olyan fene nagy áttörés, mert a jmp/call/ret stb assemblyben, gépi kódban is létezik. Ha nagyon szigorúan akarjuk venni hogy milyen új elemeket vezetett be az OOP, akkor igazad van, a polimorfizmuson kívül nem nagyon hozott újdonságot, ami korábban nem volt megoldható valahogy. Viszont egyrészt ezeknek keretet adott, másrészt a programfejlesztés és tervezés menetét jelentősen megváltoztatta, és ez volt az igazi áttörés, nem a nyelvi elemek, amik ezt "csak" támogatják. Szerintem a fenti kijelentésed túlságosan is leegyszerűsíti a dolgokat.
Szerintem is leegyszerűsítő a
Már többször jeleztem az
Már többször jeleztem az
Ezt alá tudod támasztani valamivel? Csak mert kb ez az egész buli lényege :) Aki OOP-ben programozik, igen erősen támaszkodik a polimorfizmusra, kb egész nap ezt használja. Szerintem valami félreértés van benned a fogalmat illetően.
Az adatrejtés nem irigységről, vagy arról szól, hogy "eldugjuk azt az integert, mert Igor a tundráról honnan tudhatná hogy kell vele bánni". Azért definiálunk kívülről "nem elérhető" tagokat, mert nem szeretnénk, ha azokat direkt módon kívülről megmódosíthatnák, ugyanis az az adott objektum inkonzisztens állapotához vezethet, és ki tudja milyen hibát fog okozni és mikor. Ehelyett az objektumok állapotát publikus metódusokon keresztül változtatjuk, ami biztosítja a konzisztens működést. Másrészt bármikor átírhatom interface változtatás nélkül az adott classt úgy, hogy az a változó kikerül, vagy más nevet kap benne. Tehát ezzel azt is biztosítjuk, hogy senki ne függjön egy objektum belső állapotán közvetlenül. Egyébként aki nagyon akarja, reflectionnel, vagy bizonyos nyelvekben byte code manipulációkkal úgyis hozzáférhet. De az ilyenért általában nádpálcás verés jár, néhány esetet kivéve.
Az adatrejtésről a 89-es
Az öröklődést és a polimorfizmust most egy kalap alá veszem, és csak szimplán öröklődésként hivatkozom rájuk.
Az öröklődéssel az a bajom, hogy a világot statikusan modellezi le, mivel az adatok és a hozzájuk tartozó programlogika között erős kötés van. Ha változnak az adatok – márpedig változnak, mert a világ már csak ilyen, ha blogmotornál bonyolultabb alkalmazást készítünk –, akkor emiatt sokszor macerás átírni a programkódot, ha nem felel meg az eredeti interfésznek, erre hoztam példát múltkor. Laza csatolással jóval egyszerűbb és hatékonyabb a fejlesztés, az öröklődést legfeljebb a statikus, ritkán változó helyeken tudom elképzelni, mint a programlogika, erre volt példa pár hónappal ezelőtt az inf3rno által készített beléptető osztály.
Az öröklődéssel az a bajom,
Miben erősebb, vagy statikusabb ez a kötés, mint a strukturális programozásban? Én semmi különbséget nem látok az adat és a programkód közötti kapcsolatban. Mindkét esetben tudja a kód olvasni, meg írni. Az objektum belülről nézve nem más, mint egy strukturált program.
Miért, a strukturált kód ezzel szemben átírja magát? :)
A példa, amit múltkor hoztál nem volt jó. Nyilván, amit admin módosítgathat kedvére, azt nem tesszük bele öröklési fába, mert értelmetlen. Többek között inf3rno írta le neked, hogy hogy kell ezt szépen megcsinálni OOP-ben. Illetve az olyan nyelvekben, ahol van többszörös öröklődés, ott megoldható másképp is, de pl a php nem ilyen.
A laza csatolás és a strukturált programozás ritkán fér meg egy mondatban, hisz konkrét implementáción függsz (függvényhívás), ami minden, csak nem laza csatolás. Persze van funcptr meg hasonlók, de alapvetően a strukturált programozás nagyon erős kötésekkel dolgozik. Ezzel szemben egy normálisan megírt OOP kódban nincsenek implementáción függések, kimondottan erre való pl az interface.
Lentebb láthatsz példát a laza csatolásra. Itt a TypePrinter osztály nem tud a Type interface egyetlen implementációjának létezéséről sem. Nem tudja hány van, kik azok, és mit csinálnak pontosan. Viszont bármelyik implementációjának ki tudja írni a nevét.
Az öröklődést és a
Az általad felvázolt problémára nem az öröklődés a megoldás, hanem a kompozit osztályok. Ezt le is írtuk legalább ketten.
Már beszéltünk az adatrejtés
Szerencsésnek mondhatom
Korábban volt persze sok dolgom ilyenekkel, és mivel ezek készítői is emberek, és éltek a tévedéshez való jogukkal, ezért bele kellett nyúlnom a kódjukba, és ha láthatóságot kellett emiatt módosítani, nem volt különösebb lelkiismeretfurdalásom. Megtehettem, mert a forráskód nálam volt (js, php), és nem pl. lefordított C rutinkönyvtárról volt szó.
Szerencsésnek mondhatom
Apache és moduljai, PHP és kiterjesztései, a Zend motorhoz tartozó eszközök, MySQL, a szerkesztőd és egyéb eszközök, az operációs rendszered stb.
És ha érkezett egy új kiadása a komponensnek, akkor kikerested az összes módosításod, és újra belekódoltad a forrásba? Ahelyett, hogy írtál volna a komponenshez egy burkolót vagy még kevesebb munkával leszármaztattad volna az osztályaiból a sajátod (ugye a öröklődés haszontalansága), és amikor változik az eredeti, akkor elég kicsomagold és bemásold a régi helyére.
Nem láttam még soha a kódod, de egyre inkább azt a képed fested róla, hogy fenntarthatatlan.
Apache és moduljai, PHP és
Az Ádám által felhozott
És ha többszálú programról
Erről egész könyveket írnak, be kellene küldeni a Fábry-nak, hogy adja elő :D
type angle ...function
Egyáltalán nem mindegy, hogy
Mindenképpen a „névtéren”,
Ez a része a dolognak
A függvények nincsenek benne
Ez technikailag nem számít. Ami számít, hogy először az objektumra hivatkozol, és attól kéred el a függvényt, amit használni akarsz. Amikor egy programnyelvet használsz, akkor általában az szokott érdekelni, hogy mit csinál a programnyelv, nem az, hogy hogyan csinálja azt.
Mivel oo-nál a függvények az objektumhoz vannak kötve, egy kódban egy objektum cseréjével az összes hozzá csatolt függvényt is ki tudod cserélni. Ezzel szemben procedurálisan az adatstruktúra cseréjével nem tudod kicserélni a függvényeket, amiket meghívsz rajta. Ez mind az encapsulation következménye. (Ebbe a fogalomba bele szokták keverni az adatrejtést is, pedig szerintem nem kéne. Adatrejtés nélkül is lehet objektum orientáltan programozni, pl javascriptben.)
Az encapsulation gyakorlatilag azt jelenti, hogy az adatstruktúra és az őt manipuláló függvények mindig együtt utaznak. Ezt lehet szimulálni procedurálisan úgy, hogyha closure-ként átadod az adatstruktúra mellett a hozzá tartozó függvényt is, amit használni akarsz rajta.
pl nézzük meg a szinuszos példát, van két algoritmusod, amelyeknek le szeretnéd mérni a sebességét, hogy dönteni tudjál, hogy melyiket használod:
Hogyan oldható fel ez a kód ismétlődés?
A PHP alkotói ezeket a problémákat úgy szokták megoldani, hogy hozzácsapnak még egy flag-et a paraméter listához, ami alapján a függvény majd algoritmust választ:
Megváltozott a függvény neve. Azért lett hosszabb, mert a függvény már nem csak méréssel, hanem algoritmus választással is foglalkozik. (Általában nem jó dolog, ha egy függvény két dologgal foglalkozik. Ilyenkor a legjobb, ha mind a két dolgot leadja két másik függvénynek, és ő maga csak menedzseri funkciót lát el, szóval a két új függvény megfelelő sorrendben történő hívását.)
Ami még drámaibb lett, az a függvény törzse, amin a commentekből elég tisztán látszik, hogy az algoritmus választó kód szíven találta a mérést végző kódot. Így amikor valaki olvassa a függvény törzset, akkor gondolatmenetet kell váltania egy pillanatra, amikor az algoritmus választó kód fölé ér. Ez elég nyilvánvalóan csökkenti az érthetőségét a kódnak. (H. Gábornak: a kód olvashatóságát sor megértett kód / egységnyi idő-vel lehet mérni, aztán lehet átlagolni azzal, hogy sok embernek megmutatod a kódot.)
Hogyan tudnánk mégis újra leegyszerűsíteni?
Hát if-else helyett lehetne map-et használni (ha van closure a nyelvben), az egyszerűbb szerkezet:
Tegyük fel magasabb absztrakciós szintre a menedzselést végző kódot:
Az algoritmusra hivatkozó flag helyett magát az algoritmust adtuk át. Az algoritmus választást tehát egy magasabb absztrakciós szintre tettük, ahol ténylegesen csinálni akartuk, ahelyett, hogy a magasabb absztrakciós szinten megadott adatok alapján alacsonyabb absztrakciós szinten álltunk volna neki. Hogyan volt lehetséges mindez? Az adatok mellett átadtuk a függvényt is, ami manipulálni tudja őket. A mérést végző kódunk így teljes mértékben újrahasznosult, az egész kód pedig rugalmasan módosítható, mert ha egy új algoritmust adunk a rendszerhez, akkor az a measureSinusAlgorithmSpeed függvényre - aminek a kódja alacsony absztrakciós szintű - nem fog kihatni, a hatása megáll - egy magasabb absztrakciós szinten - a függvényhívás előtt a tesztelendő algoritmusok megadásánál. A polimorfizmus gyakorlatilag ezt a rugalmasan módosítható kódot jelenti, amiben csak azt kötjük meg, hogy mit csináljon a kód, azt már nem, hogy milyen algoritmus alapján csinálja. Így a függvények között laza csatolást tudunk biztosítani, nem lesz beégetve a kódba, hogy melyik függvény melyik másikat hívja. A polimorfizmus tehát ugyanúgy procedurális sajátság, mint minden más, ami előfordul objektum orientáltan. A procedurális és az objektum orientált megközelítés egyáltalán nem két egymással ellentétes dolog, hanem az objektum orientált a procedurális lehetőségeinek leszűkítése egy megkötéssel: az adatokat és az őket manipuláló függvényeket mindig egy egységbe zárjuk.
Nézzük meg mi történik objektum orientáltan a kóddal:
Külön algoritmus osztály használatával:
Összességében tehát a polimorfizmus azt jelenti, hogy az adattal együtt az alacsonyabb absztrakciós szintű, algoritmust tartalmazó függvényt is átadjuk az őt hívó, magasabb absztrakciós szintű függvénynek. Így az alacsony szintű algoritmus cserélhető lesz anélkül, hogy a magasabb szintű függvény megváltozna. Tehát az ilyen jellegű kód könyebben karbantartható, az egyes függvények lazán csatoltak, és így tovább... A polimorfizmus nyelvtől, eszközöktől, programozási stílustól függően többféleképp megvalósítható. Az öröklés csak egy megvalósítás a sok közül. Az teljesen feladat függő, hogy éppen melyik megvalósítás a legjobb. Sok esetben nem az öröklés az.
Remélem kielégítő volt a válaszom. :-) Már megint 3 óra, hogy rohadna meg :D
Igen, ez pontosan az, amit
Ádám azt mondta, hogy a
What is Object Oriented
Láttam-láttam, visszaélsz a szerkesztői jogosultságaiddal : )
Közel jár az igazsághoz, de
Csak finomítottam az
Az encapsulation már a C-ben
Az a helyzet az OO-val (amire már Ádám is utalt párszor), hogy igazából senki sem tudja megfogalmazni, mi is pontosan, és innentől kezdve valóban nincs értelme mindenen vitatkozni.
Az encapsulation már a C-ben
Lövésem sincs a C-ről, mutasd, hogy mit tartasz encapsulation-nek!
Egy C programban ha egy
Ennek semmi köze az
Ezt nem mindenki gondolja
Encapsulation is used to hide
Rosszul gondolják, sokan keverik a data hidinggal, ami teljesen más fogalom.
wiki.object
Ez írja le helyesen, hogy mi az, hogy encapsulation. Legalábbis szerintem. De én elfogadom, hogy mások szerint a data hiding egyenlő az encapsulation-el, viszont akkor én nem az encapsulation-re gondoltam, hanem arra, hogy az adat és a hozzá tartozó függvények együtt utaznak. Akkor erre gondolom nincs szaknyelvi szó.
Szvsz aki ezeket a fogalmakat
Ezeket nem egyvalaki találta
Én sem ezeken keresztül
Van egy kérdésem a late binding-el kapcsolatban. Wikipedián azt írják róla, hogy az, hogy objektumokon keresztül érik el a függvényeket. Kérdés az, hogy akkor ha objektum helyett closure-t adok át, az is late binding e? A másik kérdés, hogyha van egy adatstruktúrám, és annak egy változójának closure-t állítok be, akkor vajon az is late binding e, ha azt utána meghívom, vagy az valami más? Nekem úgy lenne a logikus, ha a closure-t is dinamikusan kötnék a nyelvek, mert változóból mutatunk rá, nem valami statikus helyről, mint mondjuk egy névtér. Valószínűleg így is történik, de megerősítés kellene...
Btw ebben az esetben nem csak a polimorfizmus, hanem az encapsulation is a late binding következménye lenne. Ebből meg az következne, hogy annak, hogy az oo egyáltalán létezhessen, a late binding az alapja.
Van egy kérdésem a late
Megnéztem a late bindinget, neked inkább a dynamic dispatch szócikk kell. Előbbi az utóbbi egy speciális esete.
Úgy általában a first class function feltétele a dynyamic dispatch, mert fordítási időben csak a függvény interfészére hivatkozol, futásidőben derül ki, milyen függvény van ott. Ezt írtam is egy másik hozzászólásban.
Ezt nem látom, miért lenne így, de gondolom továbbra is JavaScriptben gondolkodsz :)
Ezt nem látom, miért lenne
Nem, úgy általánosságban. De most már tisztult a kép.
Nem, az adatrejtés és az
Értem, akkor én a late
Egy másik aspektusát ragadja
De én elfogadom, hogy mások
Nem egyenlő, csak összatartozó, lásd a másik válaszom.
És nem ejt gondolkodóba, hogy erre nincs szaknyelvi szó? :)
nem.
Pedig ez is encapsulation.
Okés, akkor nem az
A closure-ok és objektumok meglétének feltétele a late binding. Már csak az a kérdés, hogy az encapsulation meg a data hiding miért nem ugyanazt jelent?
Szerintem az enkapszuláció
Mindkettőnek az az eredménye,
Static és dynamic dispatch esetén is a változón keresztül történik, mert a változónak/adatnak van típusa, és aszerint van kiválasztva a művelet. A különbség annyi, hogy statikus esetén fordításkor eldől, hogy melyik műveletről van szó, míg dinamikus esetén fordításkor csak egy kompatibilis típus van meghatározva, és bármelyik implementáció állhat ott futásidőben.
Én nagyon azt érzem rajtad, hogy PHP-ban és JavaScriptben gondolkodsz. A típus fogalma szinte elválaszthatatlan a programozástól, mégis mellékes részletként kezeled. A néhány dinamikus nyelv is, amelyek nem használnak osztályokat, leírható típusokkal, hisz vehetjük úgy, hogy egy objektum meghatározza a más vagy saját osztályát (és a Ruby-ban például ez így is van, ha ad hoc bővítesz egy objektumot, akkor egy meta- vagy szellemosztály jön létre, amelynek leszármazottjává válik), de ha fordítva, a hagyományos nyelveket próbáljuk úgy kezelni, mintha csak objektumok volnának, hozzájuk csomagolt függvényekkel, akkor egy teljes a programozás elméletét támogató matematikai rendszert kidobnánk az ablakon. Szóval, szerintem a következő vállalkozásod legyen egy komoly típusrendszerrel rendelkező, statikus nyelv tanulmányozása :)
Ismerem a java-t. Nem tudom
Ádám azt mondta, hogy a
Variáljuk egy kicsit meg: azt mondtam, hogy az oo sajátossága a polimorfizmus. Az az egyetlen dolog, ami korábban nem létezett, és amitől az oo más, mint a jó strukturált kód.
A strukturált programozás az imperatív programozásra épít a blokkstruktúra bevezetésével. Az objektumorientált programozás a strukturált programozásra épít a polimorfozmus bevezetésével. A jó strukturált kód és az objektumorientált kód között az egyetlen különbség, hogy utóbbiban futásidőben (igen, az „objektumhoz kötve”) dől el, hogy melyik függvény lesz meghívva, fordítási időben egy interfész az adat típusa.
Nem, azért könnyű új függvényt hozzáadni, mert adott típushoz adod csak hozzá, nem egy interfészhez, amit több osztály implementál. Azt hiszem, egyébként látom, mi vész téged tévútra. Írj erre az utóbbira egy példát légyszi! (Tudom, hogy máshol már írtál egyszer, de most nem keresem meg, és lehetőleg te se, csak írd, ami egyből eszdbe jut.)
Variáljuk egy kicsit meg: azt
Igen, de ez nem igaz, mert closure-ban ugyanúgy átadható egy függvény az adattal párhuzamosan, és máris polimorf lesz a kód. Nézd végig a szinuszos példákat... A polimorfizmus pusztán annak a következménye, hogy egy függvényre lehet változón keresztül relatívan hivatkozni, és nem kell névtéren keresztül abszolút hivatkozni rá.
Én pont hogy az ellenkezőjét írtam. Azért nehéz új függvényt hozzáadni, mert utána az összes osztályban implementálni kell.
oo
A struktúráltnál nem muszáj
Az objektumorientáltnál sem muszáj megadni a másikra, csak akkor, ha interfészen keresztül akarsz rá hivatkozni. Ha csak az egyik konkrét osztályon akarod használni, akkor ahhoz adod meg. Ugyanez a helyzet a strukturáltnál: ha csak az egyiknél kell, csak arra írod meg, ha kell mindkettőhöz, akkor mindkettőhöz meg kell írd.
Ez nem igaz. C++-ban az osztály adatot rejt (az adattagokhoz nem férhetsz hozzá külső függvényből) és egységbezár (az osztállyal együtt deklarált függvényekből hozzáférhetsz), mégis külön kell jelöld a polimorf függvényeket. Azt hiszem, ez mutatja a legjobban azt, hogy rosszul értelmezed az egységbezárást.
Szóval az interface jelöli ki
Nem értelmezem rosszul az egységbezárást, csak a hozzá kapcsolódó szavak jelentése nem világos. Leginkább az adatrejtést és az encapsulation-t kellene tisztázni.
Nekem az jött le, hogy az encapsulation a függvények egy részének elrejtését jelenti, mert azt mondtátok, hogy oo nélkül is már volt... Ha így definiáljuk, akkor viszont nem tartozik bele az adatok elrejtése egy objektumban, illetve az objektumok megléte sem szükséges feltétele. Ehhez képest mindenki úgy hivatkozik rá, mint oo fogalom, meg hogy az adatrejtés is része... Na most akkor mi a helyzet vele?
Closure-ok esetében viszont
Megint dinamikus nyelvekben gondolkodsz: a függvénynek is van típusa, interfésze, és ahol függvényt adsz át egy változóban, ott a változó típusa ez a típus.
Műveletet és adatot is rejthetsz el és tehetsz hozzáférhetővé, illetve rendelhetsz egymáshoz. Az, hogy itt egy modulról vagy egy objektumról van szó, lényegtelen, általános elvekről beszélünk. Egy függvény esetén is érvényesül az információrejtés, mert nem láthatsz bele. Azért hivatkoznak rá oo fogalomként, mert manapság a csapból is az oo folyik.
Szóval az encapsulation
A dynamic dispatch azt jelenti, hogy változó tárolhat függvényt?
Egy függvény esetén azt
A dynamic dispatch azt jelenti, hogy futásidőben, egy indirekción keresztül dől el, hogy melyik függvény hívódik meg, míg static dispatch esetén fordításkor egy bizonyos függvény címe kerül a hívás helyére. Az adott nyelv szempontjából nem változó tárolja, nem arról van szó, hogy bekerül egy változóba a függvény, hanem arról, hogy az adat mellett a rendszer metainformációként tárol egy mutatót a típusra, ahol megtalálható a függvény címe. Ez persze az implementáció szempontjából egy változó. Az implementált nyelv szemszögéből ez része a változónak.
Mivel oo-nál a függvények az
Nem, ez nem az encapsulation, hanem a polimorfizmus következménye, ugyanis az az, ami fordítási időben megelégszik egy interfésszel, és futási időben dönti el a valódi típust és megfelelő függvényt.
Nagyon jól le tudod vezetni ezeket a koncepciókat, csak ez most nem vágott ide. Inkább cikkbe érdemes annak, aki nem érti, mint egy hozzászólásba nekem :)
Mivel minden objektum egy osztály példánya, ezért az, hogy az objektumhoz tartozik a függvény vagy a típushoz, kívülről szerintem nem megállapítható. Azt kérdezem akkor, hogy te miért tartod lényegesnek, hogy koncepcionálisan az objektumhoz tartozónak tekintsük? Szemben azzal, hogy az obkektumhoz csak egy típus tartozik, ami meghatároz egy műveletet.
Nem, ez nem az encapsulation,
Valóban ezt írtam le, de ez nem oo sajátság, a closure-nak is sajátsága mindez, ami meg nem szükségszerűen oo. A polimorfizmus valóban a late binding miatt lehetséges.
Valóban ezt írtam le, de ez
Legyünk pontosak, a zárvány itt irreleváns, az első rendű függvény a lényeg. Az pedig a ploimorfizmus egy megnyilvánulása: fordítási időben egy függvény interfészt (visszatérési típus, paraméterek száma és típusa) adsz meg, majd futási időben dől el, hogy pontosan melyik implementációját, melyik függvényt kell hívni. Ez az, ami C-ben is működik, annak ellenére, hogy a nyelv az adatok viszonyában nem ismeri a polimorfizmust.
Attól függ, hogy mit nevezel
Az adatokat és a rajtuk
Az előbb azt írtad, hogy
Pontosítottam fentebb.
Ha csak adat és implementáció
Az oo akkor se nem polimorfizmus, se nem encapsulation. Az oo objektumokkal dolgozik, az objektum meg az adatok és az őket manipuláló függvényeket tartalmazó egység. Az egységbe zárás és a polimorfizmus az objektumoktól teljesen függetlenül létező fogalmak. A polimorfizmusnak elég, ha vannak objektumok. Az encapsulation-t viszont meg kell támogatni plusz egy nyelvi elemmel, ha objektumokon akarjuk használni, vagy closure-al, vagy ppp osztállyal.
Ha csak adat és implementáció
Így van.
Ezt hívják típusnak ;)
Az Ada 1977-ben elsők közt
Ez a része már túlhaladott a vitának, közben rájöttem én is, hogy procedurális nyelvekben is van kivétel kezelés.
Én is kb ugyanerre a konklúzióra jutottam. Teljesen nyelv függő, hogy milyen eszközöket biztosítanak procedurális programozáshoz. Általában ha van oo támogatás, akkor ahhoz alapból erősebb eszközöket adnak. Nem értem, hogy miért ez a megkülönböztetés, de ez van.
Az olvashatóság teljesen
Ez nem állja meg teljesen a helyét, illetve max addig, amíg egyedül dolgozol. Ugyanis az olvashatóság nem a kód készítőjének fontos igazán (ő ismeri jól - egy darabig), hanem annak, aki utána bele fog nyúlni. Többek között ezért nem tartunk olvashatónak pl egy többszáz soros függvényt, az ugyanis igen nagy valószínűséggel több absztrakciós réteget fog kilapítani, és emiatt az olvasóját felesleges részletekkel terheli, nehezebb kihámozni belőle azt, ami érdekli. Majd a fordító kilapítja a kódot, ahogy neki tetszik. Ez mondjuk nem kimondottan csak OOP probléma, de segíteni segít benne, mivel erősen támogatja az absztrakciós szintenkénti tagoltságot (öröklődés, polimorfizmus). Aztán ezt vagy (túl)használod, vagy nem.
Ami az első cikket illeti, jól hangzik, és divat a mai modern eszközök utálása, hogy bezzeg a régi időkben. Bezzeg a régi időkben nem írtunk ilyen összetett rendszereket. Kicsit megváltozott a szoftverfejlesztés, és az új igények új, bonyolultabb toolokat, és magasabb szintű nyelveket igényelnek. Rakj össze egy komolyabb rendszerintegrációs projectet egy sima editorban egy alacsonyszintű programozási nyelvben, web service libek, ESB, MQ, meg minden nélkül. És ha itt még nem lőtted fejbe magad, akkor refaktorálj egyet :) Garantáltan kihullik a hajad. Hogy a fejlesztést támogató eszközöket meg kell tanulni használni, és azok komplexebbek egy szögegyszerű editoról? Hát... az élet kemény :)
OOP-ben is lehet írni
Linuxon rengeteg rutinkönyvtár C-ben készül a mai napig, nagy projektek is, ahol aztán nincs (közvetlenül) OOP, mégis olvasható, karbantartható kódot gyártanak, legalábbis most szúrópróbaszerűen belenéztem a libXML2 forrásába pár helyen.
Az, hogy van öröklődés és
Az ilyen kijelentéseket szoktad mérlegelni? Az öröklődés épp arról szól, hogy megspórolja neked egy interfész implementálását, az újrahasznosítani kívánt osztály példányosítását, és rengeteg függvénydefiníciót, ami semmi mást nem csinál, mint közvetít ehhez a példányhoz. A polimorfizmus pedig a típusellenőrzést végző elágazásokat iktatja ki a kódból. Úgy gondolod, hogy ezek nem segítenek olvashatóbbá és strukturáltabbá tenni a kódot?
Feltételezem, hogy soha nem fejlesztettél érdemben C-ben. A dolog ott kezdődik, hogy vagy olyan függvény- és struktúraneveket használsz, amik körülbelül egy numerikus azonosító olvashatóságával vetekednek, vagy félképernyőnyi lesz minden azonosító, hisz nincsenek névterek, és a szignatúrának nem része az argumentumlista, így két különböző típushoz nem használhatod ugyanazt a függvénynevet. C-ben nincs polimorfizmus, de nincsenek típusok sem futásidőben, úgyhogy ha valaha is szükséged lenne rá, hogy különböző típusú elemeket tárolj egy tömbben, akkor találj ki nekik egy azonosítót (ízlés szerint egy random numerikus konstanst vagy egy újabb kilométeres enumot), amit kézzel tárolj el mindegyik bejegyzés mellé. De mivel öröklődés sincs, ezért ha egy meglévő típust szeretnél kiterjeszteni, akkor jöhet a fent leírt kálvária az újradeklerálással és közvetítéssel. Mielőtt még lesöpörnéd azzal, hogy ezeket te úgysem használod, de, te is használod, csak a legkevésbé biztonságos és a legrosszabb teljesítményű megoldással, asszociatív tömbökkel. Na, C-ben olyanok nincsenek, úgyhogy még te is kénytelen lennél új típusokat definiálni. A konstruktorok és destruktorok hiányát még nem is említettem, természetesen az inicializációt és az erőforrások felszabadítását is kézzel kell végezni, utóbbiba természetesen a memóriakezelés is beletartozik. A tény, hogy függvényeket kizárólag a felső szinten lehet definiálni nem sokat segít a kód strukturálásán, és tovább terheli az amúgy is telített globális névteret…
Az első részhez: mint írtam,
C-ben a legnagyobb probléma a memóriakezelés, dehát másnak is sikerült már abszolválnia. Egyébként pont most tervezek ismét nekifutni annak, hogy folytassam a php-s projektem átírását C-re.
Nem is beszélve arról, hogy
Ebből mit szeretnél kihozni? Nem értem. Valóban, az öröklés nem if. A polimorfizmusnak pont az a lényege, hogy ne kelljen teletömni a kódodat ifekkel. Sőt, a túl sok ifet egyenesen tervezési hibának tartják.
Pedig dolgoztál olyan projecteken, ahol te is használtál névtereket, max nem vetted észre :)
Eddig még senki sem tudta
Pedig az.
Tévedés. OO környezetben
Az overengineering egyáltalán
Egyszerűség, hatékonyság
Ráadásul időhatékonyság szempontjából is jobbnak látok egy
result(0,'Hiba!')
sort, hiszen rövidebb leírni, vagyis ezzel a megközelítéssel gyorsabban végezhető a munka. Egy új fejlesztő csatlakozása esetén még mindig kevesebb idő egyszer ránézni a függvényre és megérteni azt, mint mindent már a futás helyén megérteni – elvégre ha megértésre csak egyszer van szükség, minek bonyolítsuk a kódot minden egyes meghívásnál?Én látom az OOP létjogosultságát, leginkább akkor, amikor egyes függvények csak adott kontextusban használatosak, így ilyenkor indokolatlan a globális névtérbe tolni őket. Csak az nem világos, hogy hívhatjuk-e OOP-nek azt, hogy ha bizonyos dolgok objektumok, így vannak metódusaik, de ezek mellett használunk globálisan függvényeket is általános célra, procedurálisan?
Lehet, hogy egy adott
Eleve nem is szoktunk ilyet leírni, hogy result(0, 'Hiba!'), inkább olyanok szoktak lenni, hogy throw new Error('Hiba!'), vagy throw new UnknownError(). Ugyanolyan tömör a dolog, csak felesleges konstansok nélkül, pusztán osztálynevekkel. Procedurálisan is lehet valami hasonlót csinálni, pl return error\unknown(), vagy bármi ilyesmi... Nyilván procedurálisan nehezebb, mert nincs try-catch blokk.
Ez egyáltalán nem igaz. Senkinek sincs olyan jó memóriája, hogy fejből tudja az összes projektjénél, hogy melyik milyen függvényeket használ, és melyik függvénynek mi a pontos paraméter listája. Én személy szerint már 1-2 hét után el szoktam felejteni, ha nem foglalkozom az adott projekttel.
Igazából egyik válasz sem arról szól, hogy érdemes e oo-t használni, hanem arról, hogy érdemes e olvasható kódot írni. Érdemes. Ha nem hiszed, akkor olvass el pár könyvet ezzel kapcsolatban.
Személy szerint én úgy gondolom, hogy oo-val könnyebb olvasható kódot írni, mint procedurálisan, köszönhető ez az oo megközelítéssel kapcsolatos nyelvi elemeknek: class, interface, extends, implements, new, instanceof, try-catch-finally, final, protected, private, public, stb... A névterek nem tartoznak ide, azt lehet oo nélkül is, szóval a globális névtér beszennyezése nem indokolja az oo-t. Nyilván ezeket a plusz nyelvi elemeket nem úri passzióból találták ki, hanem azért, mert megkönnyítik a munkát. Ha ezt valaki nem látja be, akkor tőlem nyugodtan írhat procedurális kódot, engem nem zavar, csak ne kerüljön a szemem elé soha a projektje, mert akkor általában a hajamat szoktam tépni...
Mostanra megint nagyon elkanyarodtunk
De itt vitatkozbi arról, hogy jó-e neki - teljesen értelmetlen, mert meg akarja tanulni.
Csak hogy valami
Kiszedtem pár dolgot, pl a tábla nevét a config-ból, a sablon string-eket onnan, ahol egyáltalán nincs rájuk szükség, sőt úgy általában mindenhonnan:
bootstrap.php
login.php
login.php
login.php
Ha ez a része megy, akkor el lehet kezdeni foglalkozni az oop-vel. A php-ben az oop ennél annyival nyújt többet, hogy
Összességében az oo megközelítés nyelvi szinten valamivel fejlettebb eszközöket nyújt, mint a procedurális. Az, hogy mekkora a különbség a procedurális szemlélettel elérhető eszközök között és az oo szemlélettel elérhető eszközök között, már teljesen nyelv függő. A magas szintű nyelvek esetében kicsit, vagy jobban, de az oo felé szokott billenni a mérleg, ha az elérhető eszközök minőségét nézzük. Az alacsony szintű nyelvek esetében csak a procedurális megközelítés használható, úgyhogy ott nincs miről beszélnünk. A magas szintű nyelvek esetében ez a viszonylag kis különbség az elérhető eszközökkel kapcsolatban elég volt ahhoz, hogy a hozzáértő emberek nagy többsége áttérjen az objektum orientált programozásra. A kevésbé hozzáértők nem feltétlen gondolták végig, hogy ez miért jó nekik, de mivel a profik azt mondták, hogy ez a jó, ezért divatból ők is áttértek. Gondolom ez az egész oo - procedurális vita abból adódik, hogy sokan csak divatból használják az oo-t, nem értenek igazán a benne elérhető eszközökhöz, és megfogalmazni sem tudják, hogy miért jobb az oo eszközök használata, mint a procedurális eszközöké. Nyilván aki a procedurális programozást magas szinten űzi, az képes egy jobb minőségű kód előállítására, mint aki az oo programozást alacsony szinten űzi, így érv mindig lesz a procedurális mellett, az oo-val szemben, ha ezek a felek vitatkoznak a témáról...
off:
Én nem szeretnék többet hozzászólni a témához, ez a végleges véleményem, eléggé átgondoltam az elmúlt napokban, és ezzel kapcsolatban a további vita szerintem szőrszálhasogatás, amire meg nincs se kedvem, se időm...
@Szita Szilárd: Én azt tudom
Én azt tudom javasolni, hogy nem az oo-t kezdd el megtanulni, hanem olvasd végig ezt a hozzászólást, és értsd meg, hogy mit miért csináltam, amikor átrendeztem a kódot, kiemeltem külön függvényekbe, stb... Amikor oo-ban programozik az ember, akkor is nagyjából ugyanígy szétválasztja a kódot témakörök szerint, külön osztályokba, névterekbe, stb... rendezi. Szóval pusztán attól, hogy ismered az oo eszközöket nem leszel jobb programozó. Attól leszel jobb programozó, ha megtanulod úgy rendszerezni a kódodat, hogy az másnak is érthető legyen. Az szinte lényegtelen, hogy mindezt oo-ban csinálod e, vagy procedurálisan. Az oo valamivel több eszközt nyújt erre, de ha nem tudod megfelelően használni ezeket az eszközöket, akkor teljesen mindegy, hogy procedurálisan, vagy oo-ban írod a kódodat, ugyanolyan nehezen érthető, nehezen módosítható, rossz minőségű kód lesz. Ha valami nem világos, akkor inkább kérdezz!
Nagyon jól összeszedted a
Alapból tetszik
Valamint nem ő csinálta, hanem te.
Kíváncsi vagyok, hogy mit hoz ki Szilárdból, én vele csináltattam volna, több idő alatt. De ha ezt ugyanolyan jól "magáévá teszi", akkor rengeteg időt-energiát spóroltál neki.
Remek összefoglaló. Le a
WebService-eknél érdekes,
Megintcsak érdekes, hogy mennyi köze van ennek az analógiának ahhoz, hogy REST fölé lehet öngeneráló klienst írni, míg SOAP fölé nem lehet. Kellene hozzá egy külön leíró, ami összeköti egymással a service-eket...
Írni fogok egy cikket
Imho emeljük ki az oo
Új témába gondolod? Indíts
Indítani fogok egyet, valami
Fájl vagy képet hogyan lehet beszúrni?
Az [img] taggel. De gráfot
Hogyan?
ASCII :)
á az nem az igazi, max fánál
hogyhogy nincs képfeltöltés?
a kódot még érteném, hogy nem akarsz vírust nyomatni, de képet...
Nem én fejlesztettem a
nem tudsz belenyúlni, vagy
jó lenne, ha lehetne képet, kódot, yed gráfot, psd-t, stb... mellékelni
Úgy döntöttem, hogy svg-ben
Ne haragudj, de