Stel ik maak een algemene class om data in op te slaan. Vervolgens wil ik ook een class maken om configuratiegegevens in op te slaan. Daar kan ik eigenlijk perfect de algemene Data class voor gebruiken.
Nu vraag ik me iets vreemds af. Wat is nu wijsheid. Om voor de configuratie gebruik te maken van de algemene data class? Dus:
<?php
$config_settings = new Data();
?>
Of is het slimmer om toch een aparte Config class te maken die de Data class extend?
<?php
class Config extends Data {
}
$config = new Config();
?>
Nu hebben we wel een aparte Config class, maar deze is wel leeg. Er staan geen methods is. Wat zou jullie voorkeur hebben?
We hebben een algemene class om data in vast te houden. Deze class kun je gebruiken voor diverse toepassingen. Bijv. om route objecten in op te slaan. Zou jij dan voor de route objecten gebruik maken van die algemene class, dus $route_collection = new DataCollection($routes), of zou jij een aparte RouteCollection class maken, die niks meer doet dan de algemene DataCollection extenden?
Dus, we hebben een algemene DataCollection class, waar we een aantal specifieke toepassingen voor hebben. We willen een route collection maken, een paths collection en een config collection. Gaan we nu zeggen $route_collection = new DataCollection($routes), of gaan we een aparte RouteCollection class maken, die niks meer doet dan de algemene DataCollection extenden? Idem voor de paths en config collection?
Een RouteCollection is meer dan een array, een RouteCollection kan ook matchen in zijn collection. Een RouteCollection heeft mogelijk ook methodes om alle routes in die collectie te prefixen. Al met al zou je in de RouteCollection praktisch elke method moeten overschrijven: Geen algemene DataCollection class dus.
Een PathsCollection, zoals al gezegd, naar mijn mening heeft een object die als array functioneert geen nut.
Een ConfigCollection, configuration moet je valideren, parsen, uitlezen en toepassen. Dit gaat veel verder dan een Collection alleen en dan ook weer: Op gegeven moment zul je gaan werken met een array van values, het heeft geen nut om dat om te zetten in een object.
Het hoeft toch ook niet een algemene data collection te zijn. Je gebruikt een algemene data class en kunt daarnaast extra methods toevoegen. In dat geval moet je dus een aparte RouteCollection class maken die de algemene data class extend.
>> Een PathsCollection, zoals al gezegd, naar mijn mening heeft een object die als array functioneert geen nut.
Op zich vind ik dat dan wel weer grappig, omdat jij ook classes bouwt om single key-value paren :)
>> In dat geval moet je dus een aparte RouteCollection class maken die de algemene data class extend.
En daar is naar mijn mening dus geen behoefte aan, aangezien je praktisch alle methods van die algemene data class moet overriden. Tevens zorgt het gebruik van een algemene class voor coupling tussen componenten van je library. Ik geloof in zo veel mogelijk losstaande componenten.
>> of gaan we een aparte RouteCollection class maken, die niks meer doet dan de algemene DataCollection extenden? Idem voor de paths en config collection?
Je moet oorzaak-gevolg omkeren. Het draait niet om het nuextenden van een class, maar om het voor laterafdwingen van een interface. Dat kan dus inderdaad betekenen dat je begint met een lege class OzzieFrameworkException extends Exception. Of, om dichter bij je concrete voorbeeld te blijven, met een class DataCollection implements ArrayAccess.
>> Ik geloof in zo veel mogelijk losstaande componenten.
Dat lijkt dan in te gaan tegen het DRY principe. Als je classes kunt hergebruiken moet je dat toch juist doen? (Even afgezien van de vraag of het in dit specifieke geval wel of niet zinvol is.)
>> Je moet oorzaak-gevolg omkeren. Het draait niet om het nu extenden van een class, maar om het voor later afdwingen van een interface.
Hoi Ward :)
Ik snap niet helemaal wat je hiermee bedoelt. Ik heb dus al een algemene data class. Behalve voor het opslaan van algemene data, kan ik deze class ook gebruiken voor meer specifieke toepassingen. Bijvoorbeeld voor het opslaan van paden.
Nu kan ik hier 2 wegen voor bewandelen.
De 1e en meest simpele:
$paths = new DataCollection();
De 2e:
<?php
class Paths extends DataCollection {
// deze class bevat geen methods
}
$paths = new Paths();
?>
Het verschil is dus dat ik in situatie 1 een algemeen, niet nader gespecificeerd object gebruik om data in op te slaan. In situatie 2 creëer ik een object dat specifiek is bedoeld voor de opslag van paden.
Beide objecten doen exact hetzelfde, maar in situatie 2 zeg je dus feitelijk: dit object is specifiek bedoeld voor de opslag van paden.
Het is een heel subtiel verschil, waarvan ik graag wil weten wat de voorkeur heeft.
>> Ik snap niet helemaal wat je hiermee bedoelt. Ik heb dus al een algemene data class. Behalve voor het opslaan van algemene data, kan ik deze class ook gebruiken voor meer specifieke toepassingen. Bijvoorbeeld voor het opslaan van paden.
Dat is precies wat ik bedoel :-) Zodra je extends of implements inklopt, ben je al een paar ontwerpfasen verder. Kennelijk heb je in dat voortraject besloten dat er verschillende soorten DataCollection-objecten zullen ontstaan en dan is class Paths extends DataCollection de meest logische oplossing. Dat je daarmee in eerste instantie één lege klasse (Paths) of misschien zelfs twee lege klassen (Paths en DataCollection) krijgt, is voor nu niet eens zo spannend; het draait erom dat je voor later een bruikbare structuur hebt.
Ik wist dus niet of mijn aanpak de juiste was, en of de 1e optie $paths = new DataCollection niet de meest logische was. Als ik echter naderhand iets moet aanpassen, dan wordt dat lastig. Dus vandaar dat ik dacht dat het misschien beter is om een PathsCollection te maken die DataCollection extends. Ik ben blij dat je het met me eens bent :)
Als ik nu ergens een PathsCollection object wil afdwingen, moet ik dan een extra PathsCollectionInterface maken? Of moet ik typehinten op de DataCollectionInterface? (zie ook mijn andere topic hierover)