PHP OPP
Üdv!
Interfészek és az Absztrakt osztályok tanulmányozásával vagyok elakadva.
Minden tiszta kivétel az hogy most az interfészek arra jók hogy megszabjuk egy származtatott osztálynak a metódusait se több se kevesebb? Eddig ezt így vettem ki.
Az absztrakt osztályoknak pedig a metódusait hogy használni tudjuk előbb definiálni kell egy származtatott osztályban ha jól értettem?
Azért gondolom hogy ez rossz így mert nem sok értelmét látom, és szeretném előbb megérteni mielőtt neki állok a kódokkal bajlódni hogy is működik : )
■ Interfészek és az Absztrakt osztályok tanulmányozásával vagyok elakadva.
Minden tiszta kivétel az hogy most az interfészek arra jók hogy megszabjuk egy származtatott osztálynak a metódusait se több se kevesebb? Eddig ezt így vettem ki.
Az absztrakt osztályoknak pedig a metódusait hogy használni tudjuk előbb definiálni kell egy származtatott osztályban ha jól értettem?
Azért gondolom hogy ez rossz így mert nem sok értelmét látom, és szeretném előbb megérteni mielőtt neki állok a kódokkal bajlódni hogy is működik : )
Szerintem ezekre a dolgokra
Én special az absztrakt osztályokat akkor használom, amikor két különböző osztálynak van néhány azonos tulajdonsága és viselkedése és ezeket szeretném kiemelni egy közös ősbe, de ugyanakkor a gyerek osztályok kiegészítő tulajdonságai és viselkedései nélkül értelmetlen lenne az ős működése, vagy éppen nem szeretném, hogy az ős önmagában példányosítható legyen.
Fontso különbség az absztract osztály és az interface között, hogy az absztract osztály tartalmazhat implementációs részt a metódusokra nézve, míg az interface, csak az osztály felületét határozza meg.
Interfacet akkor célszerű használni, mikor van egy osztályod ami egy másik osztályba tartozó objektumot vár és azzal dolgozik, de tulajdonképpen neked baromira mindegy hogy azaz objektum milyen osztályba tartozik, csupán az a fontos, hogy egy bizonyos meghatározott interface legyen amit kezelni tudsz.
Azt hiszem valami ilyesmi. :)
Példa:
Persze ez egy nagyon primitív példa, és értelme sem sok van, de jól látszik, hogy mire lehet használni az absztrakt osztályokat.
Plusz én még megemlíteném azt
De most így az interfészeknek
Tehát akkor az interfészek akkor csak azt szabják meg hogy milyen metódusoknak kell szerepelnie az adott osztályban? Így biztosítva valamit ami a helyes programozást segíti elő? Magyarán felület alatt azt érted hogy megadjuk a metódusokat amiket majd használni kell?
Amit pedig az absztrakt osztályokról írtál azt nem túlságosan értettem meg.
Átfogalmazom a kérdést. Egy absztrakt osztályt mikor létrehozunk a konstruktorban megadott rész lefut és az ott meghívott metódus betöltődnek/lefutnak ugye.
De ha van mondjuk más metódus amit nem használok az adott osztályban hanem azokat szeretném használni egy származtatott osztályban tegyük fel absztrakt osztály (MVC) esetében a front kontroller és alatta az egyes modulok kontrollerei a származtatott osztályok és az absztrakt osztály metódusait akarom használni a származtatott osztályokban. Így már a használata értelmet nyer, vagy sem?
Köszi a válaszokat!:)
Üdv Dénes!
Interface
Az absztrakt osztály akkor jó, ha egy közös viselkedést akarsz kiemelni, vagy a fenti példával élve és mindamellett kényszert akarsz alkalmazni a gyerekosztályokra.
Magyarán szólva, ha nem feltétlenül biztos, hogy a közös viselkedés implementálása célszerű, akkor használj interfacet, ha kötelező, abstractot.
Egyrészt, megette a fene, ha
Másodszor:
Tegyük fel, hogy van 10 féle vezérlőd objektumod.
Tegyük fel továbbá, hogy minden vezérlő objektumnak van egy olyan viselkedése, hogy eldönti magáról, hogy az adott usernak van e joga futtatni az adott folyamatot.
Nyilván való, hogy ezt nem fogod 10szer lekódolni, és az is nyilvánvaló, hogy olyan osztálynak nem sok értelme van önmagában példányosítva, ami csak annyira képes hogy leellenőrzi hogy lefuthat e egyáltalán bármilyen metódusa.
ekkor nyúlsz az absztrakt őshöz. A fent említett viselkedést kiemeled egy abstract ősosztályba, mivel ez a művelet mindig ugyan úgy végzendő, azonos logikával.
ebből az ősosztályból származtatsz N darab vezérlőosztályt, és minden az ősből származtatott vezérlőd képes lesz eldönteni magáról, hogy a usernak van e joga hozzá, vagy sem.
Interface:
Jobban nem tudom leírni mint poetro, csak másképpen.
Egy osztály felülete (interface-e) az általa tartalmazott publikus metódusokból áll.
A felület tehát nem más, mint az a része egy osztály objektum példányának, amelyet más objektumok elérhetnek.
Az interfacek egyébként kis projektek esetén feleslegesek. De amikor egy nagyobb projektbe vág az ember, és netán többen is dolgoznak rajta, akkor érdemes megfontolni a használatukat.
Én úgy tudtam hogy MVC-ben
Ahogy én olvastam én úgy képzeltem ezt el lépésekben hogy:
- felhasználó küldi a kérést hogy xy adatot akar meg jeleníteni
- front controller ellenőrzi hogy neki-ezt szabad-e, ha igen létrehozza az adatbázis kapcsolatot, ezután betölti a modulok vezérlőit
- a modul vezérlő elvégzi a dolgát (pl híreket lekéri)
- ezután front controller kapja vissza a főszerepet betölti a view-t, azt amit a modul szeretne.
- végül a front controller össze állítja a weblapot és elküldi a felhasználónak.
Nem így kellene működnie?:P
De, elviekben ez a helyes
Viszon ettol fuggetlenul az egyes modulok vezerloit nem az fc-bol szarmaztatod, mint ahogy nem sokkal feljebb mondtad.
Az már helyesebb megoldás ha
Abban a vezérlő egységben ami
A modulnak azért nem kell és szerintem nem is szabad tudnia róla hogy a kimenete hol fog megjelenni, mert a modul semmi mást nem csinál, csak parancsot dolgoz fel. Nem foglalkozik vele, hogy lesz-e kimenet, és ha lesz kimenet, akkor milyen és hol.
Őt csak az érdekli, hogy a parancs amire utasítják az lefusson, vagy ha nem tud lefutni, akkor értesítse róla a vezérlőt, aki eldönti, hogy ebben az esetben mit kell tenni. Egyszerű példa:
Adott egy modul, ami azzal foglalkozik, hogy a rendszerben lévő cikkeket vadássza össze.
Tegyük fel, hogy ezek a cikkek megjelennek a weboldalon egy formázott kimeneten is, illetve megjelenik egy RSS kimeneten is.
Ilyenkor mit csinálsz?
Vegyük a te eseted, amikor a modul tudja, hogy milyen view-ban fog megjelenni.
Elkezdesz vadul if-ezni a modulban, mikor a modulnak baromira semmi köze ehhez. :) A modulnak annyi a dolga hogy kommunikál az adatbázissal, és visszaadja az összes cikket egy előre definiált struktúrában.
Amíg az én verziómban semmit nem kell tenned. Egyszerűen értesíted a modult, hogy dolga van, visszaadja az adatokat, majd a visszakapott adatokat átadod egy olyan rétegnek ami semmi mással nem foglalkozik, mint azzal, hogy a kérés paramétereiből, illetve egyéb konfigurációs beállításokból összeállítja a layoutot, és lerendereli a kimenetet. Ez a réteg fogja tudni, hogy az adott modul adott parancsának eredményézhez milyen templatet kell alkalmazni, illetve hogy hol helyezkedik majd el a layouton belül, stb stb...
Tovább folytatva a gondolatmenetet: mi van ha egy harmadik viewban is meg kell jelennie? Vagy mi van ha az egyik view-nak lecseréled a nevét? A te esetedben ezektől a dolgoktól függeni fog a modul, és ez nem jó. Több munka, nehezebb kezelhetőség.
Míg ha ezekkel a dolgokkal nem foglalkozol a modulon belül, akkor ezek után ha bármilyen alkalmazásban egy olyan modulra lesz szükség ami a hírek kezeléséért felelős, ezt a modult bátran használhatod, mert nem kell alkalmazkodnia semmilyen szinten sem az őt körülvevő rendszerhez. Megkapja a paramétereit, kinyeri az információkat és visszaadja. Hogy aztán az általa kinyert információval mi történik, az már nem az ő dolga. Ha bármilyen módosulás van a megjelenítendő templateben, vagy más templatet kell alkalmazni az adott parancshoz, akkor elég egy konfigurációs beállítást módosítanod. És egy sort nem kellett újraprogramozni, vagy kiegészíteni. :)
Kevered a szezont a fazonnal.
Egy egyszerű MVC megvalósítás a weben többnyire úgy néz ki, hogy az alkalmazás megkapja a kérést, az alapján kiválasztja a megfelelő vezérlőt, ami módosítja és/vagy lekérdezi a modell adatait, végül összeállítja a kimenetet és visszaadja a választ. Ezt persze a végletekig lehet cifrázni, de a lényeg változatlan.
Értem :) Akkor lehet én
Akkor lehet én tévedek nagyon nagyot, amikor úgy képzelem, hogy egy layout összeállításához 4-5 vagy akár még több modul együttműködése is szükséges lehet. :)
Véleményem szerint a egy modulnak semmi köze a kimenethez. Ne állítson össze semmilyen kimenetet, és ne babráljon semmit. Arra legyen egy másik egység ami viszont csak azt kezeli és semmi mást. Persze lehet, hogy ugyanarról beszélünk, csak az elnevezésekkel van gond.
Nálam így néz ki egy ilyen kérés feldolgozása:
-Felhasználó elküldi a kérést.
-FrontController megkeresi a parancshoz tartozó egységet/egységeket
-Ha a futtatott egységekből jön vissza adat, nyilván meg kell őket jeleníteni ezért megkapja a kimenet összeállítását végző egység a vezérlést
-A fent említett egység összevadássza a kéréshez tartozó templateket és lerendereli az egységeket, majd összeállítja egy egésszé (vagy éppen részenként küldi el).
-A felhasználónál megjelenik a kimenet.
Az én értelmezésemben egy modul az egy olyan egység ami egy adott témakörrel kapcsolatos feladatok ellátására "szakosodott". Ahogyan te is mondtad, pl egy fórum. Egy modul alapvetően két részből tevődik össze nálam. Minden modulnak van egy vezérlőegysége, ami a bemenetet ellenőrzi, illetve azt hogy az adott modul adott művelete egyáltalán lefuthat-e a kért paraméterekkel, illetve van egy olyan rétege ami kizárólag az adatbázi / file vagy akármilyen más műveletekért felelős, ha úgy tetszik akkor nálam egy modul controllerből és modellből áll.
Ezen kívül van az alkalmazásnak egy FrontControllere ami arról gondoskodik, hogy melyik modulok szükségesek az adott parancs értelmezéséhez. Valamint van a rendszerben egy olyan réteg, ami arról gondoskodik, hogy a felhasználó milyen kimenetet kapjon maga elé, ezt nevezhetjük nálam viewnak. Mint mondtam: összeszedi a templéteket és feltölti a modulok által visszaadott adatokkal, majd összeállítja a részkimeneteket egy egésszé, majd ezt a kimenetet visszadobja a frontcontrollernek, aki meg majd eldönti hogy mit kell vele csinálni. Elküldeni, vagy éppen kesselni, vagy mindkettő, vagy akármi mást... Nevezhetjük ezeket az egységeket akárhogyan, de szerintem ettől a megvalósítástól kellőképpen rugalmassá válik a rendszer, és nem függenek az egyes rétegek a többi rétegtől.
Interface
Nemrég csináltam egy rendszert, amiben voltak bizonyos objektumok amik egy egy adatbázis tábla egy egy sorát reprezentálták.
Egy ponton célszerűvé vállt (azthiszem trace-eléshez, de már nem emlékszem pontosan), hogy ezek az objektumok legyenek bejárhatóak egy hagyományos foreach() segítségével.
Ekkor fordultam pl az interfacekhez. A phpban van egy iterator interface, amit te is implementálhatsz akármelyik osztályodban, és pont azt éred el vele, hogy foreach segítségével bejárhatóvá válik az objektum. Néha nagyon jól tud jönni... :)
Aztán egy másik példa lehet, hogy egy régebbi rendszerben az adatbázis osztályod asszociativ tömböt ad vissza a lekérdezések után, de egyszer csak eldöntitek, hogy mostantól ne tömböt, hanem objektumot adjon vissza. Ahhoz hogy ne kelljen felborítani mind a kismillió felhasználásnál a kódot, célszerű implementálni az osztályban az interface, illetve az array_access interfaceket, így a jövőben tömbként is, és objektumként is használhatóak lesznek az objektumaid. viszont nem kellett a komplett forrást átírni. :)
Így hirtelen ennyi jutott eszembe.
Remélem segít:)
Köszönöm a segítő
Kielégítő válaszokat kaptam, így már értem hogy melyik mikor célszerű!:)
Iterator és array_access,
Jól van. :) Dokler akadémián
Dokler akadémián néztem a videókat az objektum orientáltságról és ott nem igazán értettem meg a lényegét annak amiről kérdeztem hogy miért is jó és nem találtam érthető magyarázatot sem a neten de így már minden világos még egyszer köszönöm. :)
Ha rétegezed az
Igy van. Tulajdon keppen ez a