ugrás a tartalomhoz

Tervezési minták: absztrakció

deejayy · 2012. Jún. 9. (Szo), 14.14
Sziasztok,

megyek végig ezen a PHP tervezési minták cikksorozaton, és próbálom magamévá tenni a rengeteg tudást, ami ott van.

Kapásból az elsőnél megakadtam (abstract factory), és jó pár egyéb forrásból megpróbáltam betömni a kérdésektől tátongó lyukakat a fejemben.

Azt már régóta tudom, hogy a PHP-ben lehet absztrakt osztályokat definiálni, azt is tudom, hogy mit csinál, ha odaírom a class elé.

Az viszont nem fér a fejembe, hogy ennek hol venném hasznát. Tehát mikor döntök úgy, hogy egy ősosztály elé most inkább beírom, hogy abstract, vagy nem. Remek példák vannak mindenhol, amiknek közük nincs a valósághoz (Foo-Bar-Baz, Fruit-Apple-Cherry, stb), de valahogy még mindig nem látom a fától az erdőt.

Valaki fel tudna világosítani, hogy azon túl, hogy futásidőben dob egy errort, ha egy absztrakt osztályt próbálok példányosítani, milyen hozadéka van egy sima osztállyal szemben? Esetleg egy olyan példát, amit naponta használok, mint webfejlesztő? Vagy még mindig nem néztem eléggé utána? :\
 
1

Az absztrakt osztály azért

MadBence · 2012. Jún. 9. (Szo), 15.56
Az absztrakt osztály azért jó, mert egyrészt tudsz definiálni egy interfészt, amit a leszármazottaknak meg kell valósítania, másrészt default implementációkat írhatsz bele, és máris kevesebb a duplikált kód.
Amúgy nyilván meg lehet csinálni mindent absztrakt osztályok nélkül, de ha így vesszük, osztályok nélkül is meg lehet mindent csinálni :).
Amúgy igenis hasznos tud lenni egy-egy dobott error. Pl valamit elfelejtettem implementálni, akkor szól. Sokkal jobb, mint mondjuk egy sima osztályt írni üres függvénytörzsekkel.
Amúgy a final-nak is kb ugyanennyi értelme van elsőre, mert hát ugyan miért írnék felül egy metódust a leszármazottban, ha tudom, hogy nem szabad. Pedig a final is csak arra jó, hogy hibákat dobáljon, mégis használják :-).
2

default implementációkat

deejayy · 2012. Jún. 9. (Szo), 16.36
default implementációkat írhatsz bele

De ezt ugye nem-absztrakt osztállyal is megtehetem? (mert én most így csinálom)

Akkor gyakorlatilag dokumentációs célja van, ha jól veszem ki.
5

Amúgy a final-nak is kb

tgr · 2012. Jún. 10. (V), 19.02
Amúgy a final-nak is kb ugyanennyi értelme van elsőre, mert hát ugyan miért írnék felül egy metódust a leszármazottban, ha tudom, hogy nem szabad. Pedig a final is csak arra jó, hogy hibákat dobáljon, mégis használják :-).


A helyes kérdés az, hogy ugyan miért találnád ki, hogy egy metódust nem szabad felülírni?
3

Félkész osztály

szaky · 2012. Jún. 9. (Szo), 19.49
Az absztrakt osztály azért jó, mert tudsz olyan osztályt definiálni, ami önmagában még nem működőképes, hanem majd később, a leszármaztatott osztályokban lesz teljes. Pl van egy általános customUser osztályod, amelyben elkészíted a login fügvényt amit meghívsz, mikor az user bejelentkezik. De a valóságban van egy AdminUser meg egy CustomerUser osztályod (ezek vannak a customUser-ből leszármaztatva), amelyekben meghatározod az az autentikációs folyamatot(auth). Ekkor a rendszer működéséhez fontos, hogy a: ne lehessen a CustomUser osztályt példányosítani, mert önmagában az nem működik, és b: a leszármazott osztályban kell, hogy legyen egy auth fügvény. Erre jó az abstract osztály.
4

Nagyon egyszerű, lehetnek

tgr · 2012. Jún. 10. (V), 19.00
Nagyon egyszerű, lehetnek benne absztrakt függvények. Az absztrakt függvényről garantált, hogy ha megkapod az osztály egy példányát, abban implementálva van, ugyanakkor nem kell az ősosztályban implementálnod, ahol még esetleg nem lenne értelme. Hogy egy teljesen valóságközeli példát mondjak, van egy egyszerű, egy URL -> egy PHP fájl routinggal működő MVC weboldalon van egy Controller osztályod, ennek a leszármazottai az egyes útvonalakhoz tartozó kontrollerek, mindegyiknek van mondjuk egy render() függvénye, ami megmondja, hogy az adott controller mit is csinál; ekkor egyrészt elő szeretnéd írni nyelvi szinten, hogy minden Controller-leszármazottnak kötelessége lekezelni a render() hívást, másrészt viszont az ős Controllerben nem tudnál semmi értelmeset tenni bele, hiszen az nem csinál semmit. Írhatnál egy üres függvényt, ami dob egy kivételt, ha meghívják, de sokkal elegánsabb absztrakt függvényt definiálni, ráadásul így fordítási időben (ami persze nincs PHP-ben, de mindenesetre az adott alosztály betöltésekor) tudja jelezni a fordító, ha elfelejtetted implementálni, nem csak akkor, amikor megpróbálják meghívni.