[oop] basis- en verplichte methods
Ik heb een file cacher gemaakt. Nu kan het zijn dat ik ooit ook een database cacher ga maken. Iedere cacher moet een aantal vaste functies hebben (get, save, remove) en ik wil iedere cacher class in- en uit kunnen schakelen. Deze functionaliteit is voor iedere class hetzelfde. Dat deed me denken aan een tip van Wouter dat ik deze overkoepelende functies moet "bundelen" in 1 class. Hoe moet ik dit nu aanpakken?
Schematisch wil ik dus 2 classes:
Een algemene cacher class:
- deze class bevat deze methods: enable() en disable(). Deze methods werken dus ook echt.
- deze class stelt de volgende functies verplicht voor de overervende class: get(), save() en remove(). Deze functies zijn dus niet ingevuld! Er moet alleen worden aangegeven dat ze verplicht zijn.
Een file cacher class:
- deze class bevat de volgende methods: get(), save() en remove(). Hier zijn de methods wel ingevuld.
Hoe doe ik dit nu in goed OOP? Ik hoop dat het een beetje duidelijk is wat ik bedoel.
(Methods hoeven uiteraard niet uitgewerkt te worden, het gaat me alleen even om de juiste opzet.)
Gewijzigd op 30/04/2013 02:36:14 door Ozzie PHP
En dan je eigenlijke probleem: Als een klasse bepaalde methods invult, maar nog niet alles dan spreken we van een abstracte klasse:
Code (php)
Nu kunnen de subklassen deze 3 abstracte methods invullen en de klasse compleet maken.
Nu zou ik altijd nog een stapje verder gaan en een interface er bovenop zetten. Daar komen dan de methods get, save en remove in. Die hoef je dan niet meer abstract te maken in de AbstractCache klasse:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Waarom ik wil enablen en disablen... in principe staat de cacher altijd aan, dus in mijn programma flow ga ik er vanuit dat ie altijd aan staat:
Hebben we cache, haal dan de gegevens uit de cache op.
Maar het zou kunnen dat ik bijv. moet debuggen. Dan is het wel handig om 'm uit te kunnen schakelen, in plaats van dat ik telkens if-jes eromheen moet bouwen.
Zou je als laatste misschien nog even kunnen uitleggen:
- wat die interface bovenop die abstracte class eigenlijk doet?
- hoe ik de file cacher met de abstracte class moet "verbinden". Gaat dat via "extends"?
Thanks a lot!
Die interface is voor typehinten in andere klassen. Het is helemaal niet zeker dat elke cacher die abstracte klasse extend, want misschien heb je er wel een paar die die functionaliteit niet nodig heeft.
Ik heb mezelf aangeleerd altijd te typehinten op interfaces.
Een abstracte klasse is gewoon een klasse, dus inderdaad extends. Ik dacht dat je wel wat van abstracte klassen wist?
Ja, via de service container. Ik heb nog geen test-omgeving. Zover ben ik nog niet :)
"Een abstracte klasse is gewoon een klasse, dus inderdaad extends. Ik dacht dat je wel wat van abstracte klassen wist?"
Ik weet ongeveer wel hoe het werkt, maar ik gebruik het (tot op heden) niet vaak. Dus vandaar eigenlijk...
Toevoeging op 30/04/2013 12:56:20:
Ik ben eigenlijk toch wel benieuwd nog naar het wezenlijke verschil tussen het definiëren van abstracte methods in een abstracte class tegenover het gebruik van een interface. In feite komt het op hetzelfde neer, maar als ik het goed begrijp is een interface bedoeld om aan te geven welke methods in een class moeten zitten, maar... dat doe je in een abstracte class ook door abstracte methods aan te maken. Waar zit dan precies het verschil? Wanneer gebruik je wat?
Een interface definieert methods die klassen buiten de klasse zelf gaan gebruiken. Abstracte methods zijn methoden die de klasse zelf gebruikt.
Voor jou is het ongetwijfeld helemaal duidelijk wat je bedoelt met "Een interface definieert methods die klassen buiten de klasse zelf gaan gebruiken" maar voor mij niet. De methods in de interface moeten toch in de class aanwezig zij die de interface implements?
Code (php)
Hierin is getExtension echt nodig voor de werken van de abstracte klasse, en het is minder waarschijnlijk dat een klasse dit van buiten zal gaan gebruiken. Daarom zou ik deze als abstract definiëren:
Code (php)
De method load daar in tegen is juist bedoeld om te gebruiken buiten de klasse, vandaar dat ik deze in de interface zal zetten:
Andere klassen, bijv. een RoutingLoader, kunnen nu typehinten op dit interface en zo zijn ze er zeker van dat de load method bestaat.
Sidenote: Mocht er nu een klasse zijn die de getExtension method wilt gebruiken, dan moet hij natuurlijk alsnog typehinten op de abstracte klasse AbstractFileLoader.
Offtopic:
sorry voor mijn korte reactie, code typen op een tablet is ietwat lastig :)
Gewijzigd op 30/04/2013 16:11:21 door Wouter J
Offtopic:
U heeft een tablet aangeschaft?
Offtopic:
Jup, eindelijk een Microsoft Surface RT :)
Offtopic:
Ah, nice!! Bevalt ie een beetje?