Hey guys,

Ik begin het gebruik van interfaces steeds beter te begrijpen.

Nu heb ik hieronder een codevoorbeeldje. Ik wil een object met configuratiegegevens doorgeven aan een ander object Foo. Nu ben ik benieuwd hoe ik het typehinten moet aanpakken. Eerst maar eens het voorbeeldje:

<?php

class DataCollection implements DataCollectionInterface {

}

class Config extends DataCollection {

}

class Foo {

public function setConfig(DataCollectionInterface $config) {

}

}

$config = new Config($settings);
$foo = new Foo();
$foo->setConfig($config);

?>
In de setConfig method van de Foo class typehint ik nu naar een DataCollectionInterface.

Nu is mijn vraag of dit juist is. Ik typehint naar een DataCollectionInterface en daardoor weet ik dat het object wat ik binnenkrijg in de setConfig method over bepaalde functies beschikt. Prima, helemaal goed! Echter, wat ik niet weet is het object wat ik binnenkrijg ook daadwerkelijk een CONFIG object is. Het zou ook een ander object kunnen zijn, bijvoorbeeld een object waar paths of routes inzitten.

Nu is mijn vraag hoe specifiek ik moet gaan typehinten. Behalve het bovengenoemde codevoorbeeld heb ik nog 2 andere opties om te typehinten. Ik kan typehinten naar de class zelf:

<?php

class Foo {

public function setConfig(Config $config) {

}

}

?>
Of ik zou eventueel een extra ConfigInterface kunnen maken (die dan in feite overeenkomt met de DataCollectionInterface).

<?php

class Foo {

public function setConfig(ConfigInterface $config) {

}

}

?>
Wat is nu wijsheid? Hoe specifiek moet je te werk gaan?
Altijd programmeren naar interfaces, zodat je de weg naar verandering niet blokkeert.

En wat maakt het jouw uit of het een Config object is of een object dat paden of routes vasthoudt? Het enige wat de klasse moet weten is dat het object de methods heeft die de klasse gebruikt, de rest is kopzorgen voor een andere klasse.
>> Altijd programmeren naar interfaces, zodat je de weg naar verandering niet blokkeert.

Oké.

>> En wat maakt het jouw uit of het een Config object is of een object dat paden of routes vasthoudt?

Dat is dus mijn vraag. Stel een Router heeft een object nodig dat Routes vasthoudt. In de Router typehint je nu naar een DataCollectionInterface. Echter, nu kan ik in plaats van een object dat routes vasthoudt, ook een heel ander object doorgeven aan de Router, waar de Router helemaal niks mee kan. Stel dat ik een object meegeef waar paden inzitten in plaats van routes dan gaat het fout. Ja, natuurlijk... heel stom, je moet ook geen paden meegeven als er om routes wordt gevraagd. Maar het kan in dit geval dus wel.

Stel dat ik niet zou typehinten op interface, maar op class, dan zou het wel goed gaan. Echter, daar zijn zoals je zelf al zei nadelen aan verbonden. Ik zou ook een aparte RouteCollectionInterface kunnen maken, dan weet ik dat het a) om een DataCollection gaat en b) dat in het object de juiste inhoud zit (namelijk routes). Maar ik weet niet of dat dat bedoeling is. Geef je met een interface enkel aan welke methodes een object moet bezitten, of is het ook bedoeld om een bepaalde inhoud (paden, routes, config) af te dwingen?

Het zou niet mis moeten gaan je zou het verkeerde object moeten hebben doorgegeven maar het zou ook daarmee moeten lukken als ze dezelfde interface implementeren..
Reshad, dat is maar hoe je het bekijkt.

Stel ik heb een class die paden nodig heeft, maar ik geef een verkeerd object mee. Namelijk een object met routes in plaats van paden. In plaats van dat er nu een pad wordt gebruikt, wordt er een route gebruikt en de complete applicatie loopt de soep in.

Anders gezegd, 2 classes kunnen dezelfde methodes ondersteunen (ze kunnen allebei via een get() method iets teruggeven) maar wat ze terug geven kan verschillen van inhoud en tot ongewenste problemen leiden.
Maar als je een klasse hebt die een bepaalde interface implementeert.. laten we zeggen

VehicleInterface dan verwacht ik dat alle klasses die dit implementeren een voertuig zijn.

Stel ik heb een StorageInterface

dan ga ik ervanuit dat elke klasse die dit overerft dus iets gaat opslaan. Waarom jij dan een interface maakt voor alleen de get() methode is mij een raadsel.. maar misschien begrijp ik je niet goed en moet je even wat code laten zien. :p

Reageren