Melyek az objektum orientált programozás legfontosabb részei?
már vártam a bíróságos fenyegetést, az a kedvencem :D :D :D
mindig az az utolsó vergődése mielőtt tiltják
Az OOP paradigma négy fő elvre épül: egységbezárás, adatrejtés, öröklődés és a sokoldalúság.
Az egységbezárás a legkönnyebben megérthető elv, ez annyit tesz, hogy a műveleteket (metódusokat), és az adatokat egy szerkezetbe szervezzük, és ezt a szerkezetet hívjuk objektumnak. Az adatrejtés szintén nem bonyolult: a lényege, hogy az objektum állapotát leíró adatokat (pongyolán változókat, precízen mezőket) elrejtjük a külvilág elől, hogy azokat csak ellenőrzött módon lehessen módosítani.
Az öröklődés trükkösebb, a megértéséhez be kell vezetni az osztály fogalmát, ami egy objektum leírt változata. Innentől fogva objektum alatt a memóriában ténylegesen létező konstrukciót értjük, osztály alatt pedig ennek az objektumnak a formálisan leírt struktúráját. Pongyolán fogalmazva az osztály az, amit a programozási nyelvben a forráskódba beleírtál, az objektum pedig amit a változóba beleraksz. Az öröklődés azt jelenti, hogy egy osztály épít egy másik osztályra, és azt bővíti vagy módosítja. Az így létrejött gyermekosztályban nem kell újra leírni az ősosztály jellemzőit, csak az eltéréseket.
Végül a sokoldalúság azt jelenti, hogy egy objektum a változó típusától függetlenül az őt definiáló osztályban leírtak szerint működik. Vagyis, ha egy metódust te felülírsz a gyermekosztályban egy alternatív működéssel, akkor a gyermekosztályból példányosított objektum akkor is az alternatív módon fog működni, ha az objektumra mutató (vagy azt tartalmazó) változó típusa az ősosztály típusa.
A sokoldalúsághoz szokták sorolni az ún. interfészeket is. Ezek a nyelvi konstrukciók azt írják le, hogy egy objektumnak milyennek kellene lennie. Egy interfészt az különböztet meg az absztrakt osztálytól, hogy előbbi semmilyen működést nem definiál (egyes programozási nyelveken ez nem teljesen igaz), utóbbi viszont igen, legfeljebb (szándékosan) hiányosan.
E négy alapelv egyformán fontos. Az OOP-re épülnek azonban más programfejlesztési elvek. Személy szerint a legfontosabbnak ezek közül a SOLID elveket tartom. Önmagukban könyveket lehet írni erről az öt elvről. Zanzásítva a következőt jelentik:
Az "S" a "Single Responsibility", vagyis az egyszeres felelősség elve. Ez azt jelenti, hogy egy osztály egy és csakis egyfajta felelősségi körrel rendelkezik. Vagyis nem szórod tele nem oda való funkcionalitással az osztályaidat (metódusaidat se!), hanem szétszeded kisebb egységekre. Így könnyebb megfogni a kódot, és megérteni a feladatát az adott kontextusban.
Az "O" az Open-Close elv, vagyis nyitott-zárt. Akkor jó az osztály, ha bővítésre nyitott, módosításra zárt. Komplex elv, de a lényege, hogy pl. egy úszó állatot leíró osztályból ne lehessen végül repülő gép osztályt varázsolni, legfeljebb pontosítani, a részletekkel bővíteni (és így eljutni pl a kacsáig)
Az "L" a Liskov-behelyettesítési elv. Arról szól, hogy egy osztály az ősosztályával legyen csereszabatos. Klasszikus példa a négyzet-téglalap probléma. Matekból tudjuk, hogy a négyzet a téglalap speciális változata, ezért adja magát, hogy a kódban a négyzet osztály őse a téglalap legyen. OOP-ben nem így van, mivel a négyzet a téglalaphoz képest megköti, hogy a szélességnek és a magasságnak meg kell egyeznie. Ezért a Liskov-behelyettesítési elv betartása mellett valójában, hiába hasonlatosak, két különböző osztály a két síkidom. A gyakorlatban elég alattomosan kerülnek elő, és sokszor rengeteg veszélyes paraméterezéssel elbonyolított rettenetet okoz a fel nem ismerése.
Az I az Interface Segregation, vagyis az interfészek szétválasztása elv. Hasonlatos az SRP-hez (első), de ahhoz képest jóval szigorúbb és szűkebb értelmezési teret vár el. Vagyis, ha van egy VadKacsa osztályod, akkor az a különböző aspektusok szerint rövid interfészeket fog megvalósítani nagyok helyett. Pl. "RepülőÁllat", "ÚszóÁllat" stb. Így ahol a repülő állatokat kezeled, nem kell foglalkoznod azzal, hogy az a repülő állat milyen egyéb tulajdonságokkal rendelkezik, mindezek nélkül tudod röptetni. Gyakorlatban az ISP sértésekor szaporodnak az egy egyszerű művelet (metódushívás) elvégzéséhez szükséges függőségek.
Végül, de nem utolsósorban a D, a "Dependency Inversion", vagyis függőségek megfordítása azt jelenti, hogy a kódban az absztrakciókra építünk, és nem a specializációkra. Tapasztalatom szerint ezt az elvet értik meg a fejlesztők a legnehezebben, pedig az öt közül ez talán a legfontosabb. Az elv maga azt jelenti, hogy a kódbázis elemei absztrakciókon keresztül kapcsolódnak egymáshoz. Gyakorlatban absztrakt alaposztályokkal és/vagy interfészekkel valósítjuk meg a kapcsolatokat. Ilyen példa lehet az adatbázis kapcsolat: abban a kódban, ahol az adatbázisba kell illesztened egy rekordot, nem foglalkozol azzal, hogy milyen jellegű adatbázissal dolgozol, csak azzal, hogy beillesztesz egy rekordot. Ez a kód egy "Adatbázis" vagy "Tábla" interfészt kap, és ezt használja. A "Tábla" megvalósítása lép tovább, pl. "SQLTábla" specializáció irányába, de ő egy "SqlKapcsolat"-on keresztül tartja az adatbázissal a kapcsolatot, amiről viszont nem tudja, hogy milyen SQL adatbázis (mert nem kell tudnia - feltételezzük, hogy ANSI, de ennek a további boncolgatása elvezet a szivárgó absztrakció fogalmáig), azt majd az SQLKapcsolat interfészt megvalósító tényleges osztály határozza meg. Amikor ez sérül, akkor jön a fejvakarás (és gányolás) az ügyfél olyan kéréseire, hogy "oké, de akkor a bankkártyás fizetést meg kéne csinálni a Szuper Bank mellett a Trendy Bank-nak is)
Az OOP ezen túl könyvtárnyi irodalmat jelent, százezer mintával, amik mind-mind más és más aspektusra építenek. Nincs sorrend, mind a négy egyformán fontos.
Pongyolán fogalmazva az osztály az, amit a programozási nyelvben a forráskódba beleírtál, az objektum pedig amit a változóba beleraksz.
Micsoda?
Elárulom magam, én vagyok a 12-es. A helyzet az, hogy nagyjából 15 éve vagyok a pályán, ebből több, mint 5 éve mint architect. Nyilván messziről jött ember azt mond amit akar, de legőszintébben állíthatom, hogy láttam már karón varjút.
Nos, úgy tűnik, hogy finoman szólva sem értetek egyet a felsoroltakkal. Nos, vitassuk meg. Miben nincs igazam? Hol tévedek? Mi a helyes válasz?
Habár olyan terminus technicus-okkal, mint hogy mi a különbség az osztály és az objektum komoly bátorságra vall vitatkozni, de hitem szerint a vita visz előre, és nincs annál izgalmasabb dolog, amikor a junior mutat rá egy hibára, vagy következetlenségre az én pull request-emben.
Szóval vegyük úgy, hogy a #12-es hozzászólás egy pull request, és vitassuk meg, hogy mit kell benne módosítani ahhoz, hogy végül a közös tudásbázis része lehessen.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!