Opzet
De laatste tijd ben ik wat bezig met design patterns en software architecture. Momenteel zit ik wat te kijken naar het MVC model, en met name naar de data laag. Ik ben bezig een simpele applicatie te schrijven in PHP / MySQL waarin eigenlijk alleen de data laag voorkomt, gewoon om te zien hoe ik deze het beste kan implementeren. Ik kom alleen wel een probleem tegen.
De Table Data Gateway gebruik ik op het moment om bij m'n tables te komen. Hierin zitten dus functies als find, update, insert. In de database zit bijvoorbeeld een veld 'albums' met wat testdata. Als ik een album met id 1 wil vinden, kun je dus find(1) gebruiken.
Probleem
Op een website zijn meerdere pagina's. Zo is er bijvoorbeeld een pagina waar een lijst met albums te zien is. Ook is er een pagina waar alle informatie over een specifiek album te zien is. Voor deze twee pagina's heb je eigenlijk twee verschillende functies nodig: de lijst pagina wil alleen de album_id en album_name (SELECT id, name FROM...), de view_album pagina wil (bijna) alle informatie (SELECT * FROM ...). Je zult dus ergens het onderscheid moeten maken om uiteindelijk op de twee verschillende queries uit te komen. Mijn probleem is dus: waar zit dat onderscheid?.
Ik zie 4 mogelijke manieren om dit op te lossen;
Er is vast een algemeen geaccepteerde manier om dit op de juiste manier te doen. Ik heb wat geprobeerd te googlen maar kon hier niet erg veel over vinden. Zelf al zou je niet de Gateway gebruiken vind ik dit nog een moeilijk probleem. Je wilt de SQL allemaal bij elkaar hebben, maar tegelijkertijd wil je dat je alles op verschillende manieren kunt ophalen. Heeft iemand hier ervaring mee?
De laatste tijd ben ik wat bezig met design patterns en software architecture. Momenteel zit ik wat te kijken naar het MVC model, en met name naar de data laag. Ik ben bezig een simpele applicatie te schrijven in PHP / MySQL waarin eigenlijk alleen de data laag voorkomt, gewoon om te zien hoe ik deze het beste kan implementeren. Ik kom alleen wel een probleem tegen.
De Table Data Gateway gebruik ik op het moment om bij m'n tables te komen. Hierin zitten dus functies als find, update, insert. In de database zit bijvoorbeeld een veld 'albums' met wat testdata. Als ik een album met id 1 wil vinden, kun je dus find(1) gebruiken.
Probleem
Op een website zijn meerdere pagina's. Zo is er bijvoorbeeld een pagina waar een lijst met albums te zien is. Ook is er een pagina waar alle informatie over een specifiek album te zien is. Voor deze twee pagina's heb je eigenlijk twee verschillende functies nodig: de lijst pagina wil alleen de album_id en album_name (SELECT id, name FROM...), de view_album pagina wil (bijna) alle informatie (SELECT * FROM ...). Je zult dus ergens het onderscheid moeten maken om uiteindelijk op de twee verschillende queries uit te komen. Mijn probleem is dus: waar zit dat onderscheid?.
Ik zie 4 mogelijke manieren om dit op te lossen;
- Geen onderscheid maken. Gewoon altijd alles ophalen en teruggeven (SELECT * FROM...) en de functie die dit aanroept laten beslissen wat hij wil en niet nodig heeft. Nadeel: performance
- Verschillende find() functies in de gateway maken. Bijvoorbeeld findForList() en findFullAlbum() of iets dergelijks. Er moet dan wel goed bijgehouden worden wat de functies precies returneren. Nadeel: lelijk, en je kunt uiteindelijk aardig wat verschillende functies krijgen wat erg onoverzichtelijk wordt
- Aan de functie meegeven wat je wilt hebben. Zo kun je find(id) veranderen naar find(id, select) zodat je als argument meegeeft welke velden je precies wilt hebben. Echter, zo wordt meteen duidelijk dat het probleem eigenlijk groter is: wat als je ook een LIMIT wilt? Of een ORDER? Moet dit ook meegegeven worden? Nadeel: nu ben je al meteen een query builder aan het maken, iets wat ik persoonlijk niet heel prettig vind omdat je volgens mij dan beter gewoon queries kan meegeven. Is een stuk duidelijker.
- Queries aan de gateway geven. Zo kan elke pagina gewoon precies vragen wat deze nodig heeft. Een lijst pagina wil iets als SELECT id, name FROM albums ORDER BY date_added LIMIT 5 of SELECT id, name FROM albums WHERE FIRST_LETTER(name) = 'a' ORDER BY name (geen correcte MySQL, maar you get the point). Op deze manier is het duidelijk te zien wat er precies gevraagd wordt. Nadeel: de SQL verplaatst zich nu naar de klasse die de Gateway gebruikt, iets wat juist niet de bedoeling is. Ook krijg je hierdoor code duplicatie wanneer twee verschillende pagina's juist wel hetzelfde willen hebben. Al is dit misschien op te lossen door queries die meerdere keren gebruikt worden juist wel in de Gateway te stoppen. Dan krijg je echter de SQL op twee verschillende 'lagen'.
Er is vast een algemeen geaccepteerde manier om dit op de juiste manier te doen. Ik heb wat geprobeerd te googlen maar kon hier niet erg veel over vinden. Zelf al zou je niet de Gateway gebruiken vind ik dit nog een moeilijk probleem. Je wilt de SQL allemaal bij elkaar hebben, maar tegelijkertijd wil je dat je alles op verschillende manieren kunt ophalen. Heeft iemand hier ervaring mee?