[oop] objecten meegeven?
Ik ga een cacher class maken en nu wil ik dat iedere website op mijn server een eigen mapje krijgt.
Nu werk ik met een service-container en ik heb mijn service-container zo gemaakt, dat ik ook een service als argument kan meegeven aan een andere service.
Zoals ik hierboven aangeef, heeft iedere website z'n eigen cache folder. Het pad naar deze folder bestaat uit een "vast" gedeelte (namelijk /pad/naar/cache/) en een dynamisch gedeelte (bijv. www.site1.nl) dat wordt gegenereerd op basis van het request.
Nu kan ik op het moment dat ik de cacher wil gebruiken 2 dingen doen:
1)
Ik genereer van tevoren het pad naar de cache folder en stel dat vervolgens in via een setCachePath(). Dan krijg je dus (globaal) zoiets:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$cache_path = $container->get('paths')->get('cache') . $container->get('request')->get('domain');
$cacher = $container->get('cacher');
$cacher->setCachePath($cache_path);
?>
$cache_path = $container->get('paths')->get('cache') . $container->get('request')->get('domain');
$cacher = $container->get('cacher');
$cacher->setCachePath($cache_path);
?>
2)
Wat ik ook kan doen, en ik eigenlijk mooier vind, is om de 'paths' service (object) en de 'request' service (object) als argumenten mee te geven aan de cacher service. Op het moment dat ik dan de cacher service aanroep, wordt het paths object en het request object aan de constructor van de cacher meegegeven, en de constructor bepaalt dan vervolgens zelf het cache path.
Ik vind dit een mooiere optie, omdat ik dan in de code geen cache path hoef in te stellen. Dat doet de cacher immers zelf. Het enige "nadeel" wat ik me zou kunnen bedenken, is dat ik dan wel 2 objecten moet meegeven aan de cacher. Is dat "lelijk" OOP, of is dit juist zoals het zou moeten?
Graag jullie mening.
Gewijzigd op 14/04/2013 11:45:00 door Ozzie PHP
Wat wel heel erg verkeerd is is dat je hierdoor de cacher afhankelijk maakt van de Request klasse. Daar heeft die cache klasse niks mee te maken. De taak cachen is het opslaan van gegevens in een bepaalde resource. Een FileCacher heeft als taak gegevens op te slaan en op te halen uit een bestand. Wat dat bestand is heeft de cacher niks mee te maken, het enige dat hij hoeft te weten is dat hij schrijf en lees toegang tot dat bestand heeft.
Thanks voor je reactie Wouter. Uhm, oké... maar de cacher zal moeten weten WAAR hij z'n bestanden moet lezen en schrijven. Dat kan ik dus "handmatig" meegeven (optie 1), of ik geef die 2 objecten mee, en de cacher weet vervolgens zelf de locatie waar hij de bestanden moet lezen en schrijven. Ik vind de 2e optie mooi omdat ik dan handmatig niks extra's hoef te doen zoals bij optie 1 wel het geval is. Maar jij vindt optie 2 dus niet goed? (Heb je een alternatief?)
Als de cacher zelf vanuit één of andere request klasse de bestandslocatie moet gaan raden heeft de cacher toch 2 verantwoordelijkheden? Als eerste moet hij gaan nadenken waar het bestand staat en vervolgens moet hij ook nog met dat bestand gaan werken. Dat betekend dat je hem niet kunt hergebruiken. Stel dat je straks verder in dit project ook globale gegevens wilt gaan cachen. Dan moet je weer een hele nieuwe cache klasse maken omdat je dan niks meer met de Request te maken hebt.
Wat je dus moet doen is deze 2 verantwoordelijkheden in 2 klassen stoppen. Je hebt dan bijv. een FileCache en een CacheContext klasse. De FileCache is slechts een klasse die dingen kan opslaan in bestanden. Welk bestand dat is dat krijgt hij doormiddel van een bestandsnaam mee.
De CacheContext klasse is een klasse die een Request klasse krijgt en aan de hand daarvan bepaald welke bestandsnaam hij aan de FileCache meegeeft.
Maar in mijn geval zal de cache altijd in dezelfde map plaatsvinden. Dan kan ik toch wel het (basis)pad opslaan in de cache class?
Nee, wie zegt dat het altijd in dezelfde map plaats vind? In je volgende project is er weer een andere map, ga je dan weer die klasse aanpassen? En in een ander project weer?
Iedere website krijgt een vaste cache map:
Die map verandert niet... nooit. Dus vandaar mijn vraag.
(offtopic: dat zal in jouw geval elke opdracht zijn... ;-) wil je niet weer een Cache klasse moeten maken, maar wil je gewoon deze cache klasse gaan gebruiken. Daarom moet je zorgen dat je nergens instellingen hard-coded in de klasse.
Maar je maakt die Cache klasse niet voor alleen dit project. Als je straks later een andere opdracht krijgt waarbij je ook moet gaan cachen Overigens ga ik het niet hard-coded opslaan hè... het pad wordt dynamisch gegenereerd.
Een het genereren van een path is natuurlijk hetzelfde als het hard-coded opslaan van het path.
Ah ja, daar heb je een punt. Ik ga er eens even goed over nadenken wat het handigste is. Jij hebt het trouwens over "file" cachen hè. Welke andere manieren van cachen zijn er dan nog meer?
- https://github.com/zendframework/Component_ZendCache/tree/master/Storage/Adapter
- https://github.com/doctrine/cache/tree/master/lib/Doctrine/Common/Cache
- https://github.com/tedivm/Stash/tree/master/src/Stash/Driver
Ik geloof niet dat ik er zoooveel nodig heb, hahaha...
Naja, een paar zijn er wel handig. Ik zou zelf DataBaseCache, FileCache, ApcCache en ArrayCache (handig voor testen) gebruiken.
Waarom zou je iets in een database willen cachen?
Een andere reden kan zijn dat het genereren van de content simpelweg te lang duurt om het voor iedere request te doen. In dat geval maak je het alleen de eerste keer aan en kan je het daarna ophalen wanneer het nodig is. Dat soort cache kan je prima in een database opslaan.
Dankjewel voor je uitleg. Maar waarom zou je het dan in je database opslaan en niet in een bestand? Dat laatste is toch sneller om te benaderen?
Ten eerste is dat zeker niet altijd het geval en ten tweede zijn er natuurlijk nog veel meer voordelen aan het gebruik van een database die ik hopelijk niet allemaal uit hoef te leggen....
Ik hoop dat je mij kunt uitleggen in welke gevallen (praktijkvoorbeelden) het beter is om iets in de database te cachen in plaats van in losse bestanden. Ik heb zelf namelijk geen idee, maar wellicht kun je mij overtuigen en kan ik het straks zelf toepassen. Maar op dit moment is het waarom me nog niet duidelijk. Dus graag jouw uitleg.
Andere redenen zijn bijv:
- Het parsen van Yaml/Xml configuratie bestanden, dat ga je natuurlijk niet elke request doen
- Het parsen van templates
- Ipv elke request een hele rij bestanden te doorzoeken opzoek naar 1 of 2 bestanden sla je deze bestanden op, waardoor je deze bestanden direct kunt aanroepen
- ect.
Ja, tot zover snap ik het allemaal wel... maar ik ben dus benieuwd waarom je de gegevens die je cachet zou opslaan in een database in plaats van in een bestand? Dat is het enige wat ik graag wil weten.