[oop] interface of datamapper voor vimeorequest ?
Ik moet voor een klein project vimeo data ophalen uit verschillende resources. Ik heb hiervoor een interface gemaakt die als basis dient voor de classes, maar is dit wel de juiste benadering? Hoe zouden jullie dit aanpakken?
Dit is mijn code:
VimeoRequest.interface.php :
VimeoDatabaseRequest.model.php :
Code (php)
1
2
3
2
3
class VimeoDatabaseRequest implements VimeoRequest {
public function get($id) { // fetch from database }
}
public function get($id) { // fetch from database }
}
VimeoCurlRequest.model.php :
Code (php)
1
2
3
2
3
class VimeoCurlRequest implements VimeoRequest {
public function get($id) { // fetch from vimeo source thru curl }
}
public function get($id) { // fetch from vimeo source thru curl }
}
Vervolgens kan je de request doorgeven aan een VimeoVideo object die de get() functie uitvoert:
Instantie :
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
$video = array(
0 => '37298',
1 => '38098'
);
$curl_mapper = new VimeoCurlRequest();
$video = new VimeoVideo($video[0], $curl_mapper);
echo $video->render();
$db_mapper = new VimeoDatabaseRequest();
$video = new VimeoVideo($video[1], $db_mapper);
echo $vimeo->render();
0 => '37298',
1 => '38098'
);
$curl_mapper = new VimeoCurlRequest();
$video = new VimeoVideo($video[0], $curl_mapper);
echo $video->render();
$db_mapper = new VimeoDatabaseRequest();
$video = new VimeoVideo($video[1], $db_mapper);
echo $vimeo->render();
Ik hoor graag of dit een correcte benadering is.
Groetjes, Ken
Gewijzigd op 25/03/2014 19:05:27 door Ken PHP
Dat ziet er wel goed uit ja.
Ik heb wel wat andere bedenkingen over je code:
- De Vimeo*Request klassen fetchen een VimeoVideo klasse. Wat jij nu doet is een VimeoVideo klasse aanmaken en dan zichzelf laten fetchen. Of dit is een probleem in de naamgeving, of je doet hier iets verkeerd.
- Kijk eens naar namespaces, die maken je code al snel een stuk mooier met al die Vimeo prefixen :)
- Een kleine tip: Probeer de naamgeving van je methoden te baseren op wat je normaal zou zeggen. Je code moet eigenlijk gewoon een verhaal worden. Gebruik niet dingen als "get" waar ze eigenlijk niet in de zin zouden passen. Je doet dit alleen maar omdat developers nou eenmaal vinden dat het "get" moet zijn. In je beide comments heb je het al over "fetch from ...". fetch zou dus een veel mooiere naam voor deze method zijn.
- Leer om netjes in te springen. Nu doe je het vaak niet, soms met 1 spatie, etc. Gebruik een tab of 2 a 4 spaties, dan wordt je code het meest overzichtelijk.
Wouter J op 25/03/2014 22:08:27:
Wat jij hier hebt is het Adapter pattern. En dat is perfect voor deze situatie.
Cool, thanks! Hierover heb ik inderdaad een keer wat gelezen, zal het er weer eens bij pakken.
Wouter J op 25/03/2014 22:08:27:
Ik heb wel wat andere bedenkingen over je code:
- De Vimeo*Request klassen fetchen een VimeoVideo klasse. Wat jij nu doet is een VimeoVideo klasse aanmaken en dan zichzelf laten fetchen. Of dit is een probleem in de naamgeving, of je doet hier iets verkeerd.
- De Vimeo*Request klassen fetchen een VimeoVideo klasse. Wat jij nu doet is een VimeoVideo klasse aanmaken en dan zichzelf laten fetchen. Of dit is een probleem in de naamgeving, of je doet hier iets verkeerd.
Ik begrijp je gedeeltelijk. Ik besef wel dat dit onderdeel nog wat extra uitwerking kan krijgen. In VimeoVideo doe ik nu wat basis validaties zoals controleren of het id numeric is, en haal ik via deze functie de video op:
Daarna kan ik op basis van de video data de ratio en het formaat bepalen en de url opbouwen met extra configuraties zoals kleur, title etc. Als laatste kan je dmv de render() functie aanroepen die een andere class instantieert om de view te bouwen.
Wouter J op 25/03/2014 22:08:27:
- Kijk eens naar namespaces, die maken je code al snel een stuk mooier met al die Vimeo prefixen :)
Ja, dat is een goede next step! :)
Wouter J op 25/03/2014 22:08:27:
- Een kleine tip: Probeer de naamgeving van je methoden te baseren op wat je normaal zou zeggen. Je code moet eigenlijk gewoon een verhaal worden. Gebruik niet dingen als "get" waar ze eigenlijk niet in de zin zouden passen. Je doet dit alleen maar omdat developers nou eenmaal vinden dat het "get" moet zijn. In je beide comments heb je het al over "fetch from ...". fetch zou dus een veel mooiere naam voor deze method zijn.
Goede tip! Zal ik wat meer op letten.
Wouter J op 25/03/2014 22:08:27:
- Leer om netjes in te springen. Nu doe je het vaak niet, soms met 1 spatie, etc. Gebruik een tab of 2 a 4 spaties, dan wordt je code het meest overzichtelijk.
Ja, dit doe ik al maar komt hier niet echt tot zijn recht, sorry :)
--
Mocht je meer input hebben dan hou ik mij aanbevolen!
Thanks!
Gewijzigd op 26/03/2014 09:46:19 door Ken PHP
Quote:
Ik begrijp je gedeeltelijk. Ik besef wel dat dit onderdeel nog wat extra uitwerking kan krijgen. In VimeoVideo doe ik nu wat basis validaties zoals controleren of het id numeric is, en haal ik via deze functie de video op:
[..code..]
Daarna kan ik op basis van de video data de ratio en het formaat bepalen en de url opbouwen met extra configuraties zoals kleur, title etc. Als laatste kan je dmv de render() functie aanroepen die een andere class instantieert om de view te bouwen.
[..code..]
Daarna kan ik op basis van de video data de ratio en het formaat bepalen en de url opbouwen met extra configuraties zoals kleur, title etc. Als laatste kan je dmv de render() functie aanroepen die een andere class instantieert om de view te bouwen.
Oke, tijd om je het SOLID principe te introduceren. SOLID is een afkorting voor de belangrijkste OO principes:
- Single Responsibility Principle
- Open/closed principle
- Liskov's Substitution
- Interface Segregation
- Dependency Inversion
Er is een goede tutorial serie hierover op code tuts+, ik raad je zeker aan om die door te lezen: http://code.tutsplus.com/tutorials/solid-part-1-the-single-responsibility-principle--net-36074
Maar voor nu kijken we even naar de S: Single Responsibility Principle. De definitie van dit principe: Een klasse/method zou maar 1 rede moeten hebben om te veranderen.
Nu kijk ik even naar wat jij me hebt uitgelegd over de VimeoVideo klasse:
- Het houdt een basis ID vast
- Het valideert de ID
- Het fetch een instance van zichzelf
- Het berekend wat onbekende parameters
- Het maakt een URL
- Het rendert een widget van zichzelf
Dit zijn 5 redenen waarom wij de VimeoVideo klasse zouden moeten aanpassen. Stel het fetchen veranderd of er komen meer onbekende parameters bij. Of de URL veranderd. Of .... Allemaal redenen waarom we die klasse moeten aanpassen, dit zou er maar 1 moeten zijn.
Om dit te veranderen gaan we elke rede een eigen klasse geven.
We krijgen dus een VideoId klasse. Dit is een zogenoemde Value Object. Het enige wat deze doet is een value vasthouden en valideren of hij wel klopt.
Vervolgens hebben we een DataMapper. Deze krijgt een VideoId en geeft een nieuwe instance van een Video object terug.
We hebben ook een VideoParameterResolver, deze berekend de onbekende parameters.
Daarnaast hebben we nog een VideoUrlGenerator en een VideoWidgetRenderer.
Een voorbeeld code:
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
<?php
use Ken\Vimeo\Video\DataMapper\Request as RequestDataMapper;
use Ken\Vimeo\Video\Id as VideoId;
use Ken\Vimeo\Video\ParameterResolver;
use Ken\Vimeo\Video\UrlGenerator;
use Ken\Vimeo\Video\Widget\Simple as SimpleWidget;
$videoMapper = new RequestDataMapper(...);
$video = $videoMapper->fetch(new VideoId(124));
$resolver = new ParameterResolver(...);
$video = $resolver->resolve($video);
$urlGenerator = new UrlGenerator(...);
$widget = new SimpleWidget($video, $urlGenerator);
echo $widget->render();
?>
use Ken\Vimeo\Video\DataMapper\Request as RequestDataMapper;
use Ken\Vimeo\Video\Id as VideoId;
use Ken\Vimeo\Video\ParameterResolver;
use Ken\Vimeo\Video\UrlGenerator;
use Ken\Vimeo\Video\Widget\Simple as SimpleWidget;
$videoMapper = new RequestDataMapper(...);
$video = $videoMapper->fetch(new VideoId(124));
$resolver = new ParameterResolver(...);
$video = $resolver->resolve($video);
$urlGenerator = new UrlGenerator(...);
$widget = new SimpleWidget($video, $urlGenerator);
echo $widget->render();
?>
Dit is ook wel een fijn artikel:
http://juniorgrossi.com/2013/be-a-better-php-developer/
Nogmaals bedankt!
Gr, Ken