Archief - design patterns

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

GizeH

Legacy Member
Ik programmeer al een lange tijd in php, en begrijp wel het principe van MVC, maar heb dit nooit echt toegepast omdat ik problemen heb om dit toe te passen in een project.
Voorbeeld: je hebt een blog pagina, waarin je berichten toont, maar ook de poster. Bovendien zie je op deze pagina ook per blogpost, de eerste 10 comments.

Je hebt dus blog, user en comment model.

Hoe en waar haal je nu de juiste data op? (omdat deze uit alle 3 de models komen...)

Kan iemand mij eventueel een boek aanraden die meer de gedachtengang hierachter uitlegt? het technische aspect van MVC ken ik, maar hoe je dit nu precies toepast irl, dit begrijp ik minder. (tenzij de simpele tutorials waarbij slechts 1 model zonder relaties enzo gebruikt worden...

Zijn er verder nog andere zaken waar ik meer over zou moeten weten om minder "spagetti code" te schrijven? (dingen zoals dependency injection, ...)

Ik heb wel een basiskennis van OOP, maar enkel de technische kant, en niet hoe je het nu echt gaat toepassen...

KenSpectre

Legacy Member
K, dus je kent het basis principe?

Wel in dit geval kan je dan 3 models maken: de user, de blog (dus de effectieve post), en de comment models).

In je controller krijg je dan bv je id mee van de blogpost. Dus in je controller kan je dan doen:
$blogModel = new blogModel();
$post = $blogModel->loadPost($id);

Dit haalt dan je blogpost op.
Deze kan je dan doorgeven aan de view in de controller:
$this->view->post = $post;

En dan in je view kan je doen:
<?php echo $this->view; ?>

Nu wil je natuurlijk ook de laatste blogcomments. Dit kan je doen in je load van de blogModel, dan komt er een extra parameter bij voor bv het aantal te weten of je kan deze ook apart ophalen.
$commentModel = new commentModel();
$comments = $commentModel->getLastComments($blogid, $amount);

Ook deze kan je op dezelfde manier in je view showen.

Nu de users voor elke comment zou ik al ophalen met de 'getLastComments' methode. Anders word je controller nogal 'dik' zoals ze zeggen.

Ik weet niet of je al gehoord hebt van lean controllers? Dat betekent dat eigenlijk zoveel mogelijk in het model wordt gedaan. In dit geval zou dat dus beteken dat loadPost niet alleen de blogpost zou moeten ophalen, maar ook de comments en de users. Natuurlijk maakt die functie dan gebruik van de andere 2 models (Comments en Users). Dit is dan weer compleet anders dan hoe ik het hier beschrijf.

Het is vooral kijken en zoeken hoe je het het best kan doen. En dit per project.

Nog een andere manier die wij op het werk bv gebruiken is Doctrine. Deze haalt practisch alles voor je op als je je database opstelt volgens hun regels.
Doctrine URL
Echter zou ik hier nog even mee wachten.

Indien je nog vragen hebt stel ze gerust. Ik hoop dat het een beetje duidelijk is.

Vergeef me de PHP code, ik ben gewoon om te werken met Zend :)

GizeH

Legacy Member
Bedankt voor de uitleg.

Via gewone php, schrijf ik de volgende query:

$data = SELECT blogitems.*, users.* FROM blogitems, users WHERE blogitems.id_users = users.id

dan heb ik een array met alle blogitems en de poster gegevens.

Als ik dit nu via het mvc principe doe, zou ik in de blogmodel bvb de functie
getAllBlogitems() hebben. Hierin zitten alle blogitem rijen.
Het lijkt mis als er in die functie ook gegevens opgehaald worden mbt de blogitem poster?

Dus in de usermodel zou ik dan bvb een functie getUserById() hebben
en dan zou ik het volgende kunnen doen:

$blogitems = blogmodel->getAllBlogitems();
foreach($blogitems as $key => $blogitem) {
$blogitems[$key]['poster'] = usermodel->getUserById($blogitem['id_users']);
}

Dit lijst mij juister, of toch niet?
Het nadeel is hierbij dat het teveel db queries oplevert...

Mag je in een model gegevens van verschillende tabellen ophalen?

Idem met
$comments = $commentModel->getLastComments($blogid, $amount);
dit betekent dat voor ieder blogitem bovenstaande getLastComments() functie moet opgeroepen worden, wat traag zal zijn.

KenSpectre

Legacy Member
GizeH zei:
Bedankt voor de uitleg.

Via gewone php, schrijf ik de volgende query:

$data = SELECT blogitems.*, users.* FROM blogitems, users WHERE blogitems.id_users = users.id

dan heb ik een array met alle blogitems en de poster gegevens.

Als ik dit nu via het mvc principe doe, zou ik in de blogmodel bvb de functie
getAllBlogitems() hebben. Hierin zitten alle blogitem rijen.
Het lijkt mis als er in die functie ook gegevens opgehaald worden mbt de blogitem poster?

Ja en nee, Het is idd zo dat je dan niet meer puur alleen de blog post ophaalt. Echter haal je wel essentiele informatie op (de poster) dat in principe wel deel uitmaakt van een blogpost. Vandaar dat ik zei dat je het een beetje per project / situatie moet bekijken.

GizeH zei:
Dus in de usermodel zou ik dan bvb een functie getUserById() hebben
en dan zou ik het volgende kunnen doen:

$blogitems = blogmodel->getAllBlogitems();
foreach($blogitems as $key => $blogitem) {
$blogitems[$key]['poster'] = usermodel->getUserById($blogitem['id_users']);
}

Dit lijst mij juister, of toch niet?
Het nadeel is hierbij dat het teveel db queries oplevert...

Opnieuw is dit iets wat je per project moet bekijken. In dit geval is de poster essentiele informatie van de blogpost. Daarnaast is het idd zo dat je hier vaker je database zal moeten aanroepen. In dit geval zal het echter weinig verschil maken, met grotere projecten daarentegen kan dit wel een verschil maken.

GizeH zei:
Mag je in een model gegevens van verschillende tabellen ophalen?

Omdat een user een essentieel onderdeel is van een blogpost ben ik overtuigd van wel.

GizeH zei:
Idem met
$comments = $commentModel->getLastComments($blogid, $amount);
dit betekent dat voor ieder blogitem bovenstaande getLastComments() functie moet opgeroepen worden, wat traag zal zijn.

Ja, en hoewel dit ook een onderdeel is van een blogpost is ze niet essentieel. Je kan perfect een blogpost lezen zonder de comments.
Aan de comments horen natuurlijk wel een blogpost, anders heb je geen context.

Jerre Muesli

Legacy Member
Als je maar in heel bepaalde gevallen de users nodig hebt kan je ze best apart ophalen. Anders vervuil je toch maar je model. Als je te specifieke queries maakt voor elk scherm geraak je vroeg of laat in de problemen omdat je door het bos de bomen niet meer ziet. Voorts zou ik geen query in een loop uitvoeren maar proberen om alle info in 1 query op te halen.

KenSpectre

Legacy Member
Jerre Muesli zei:
Als je maar in heel bepaalde gevallen de users nodig hebt kan je ze best apart ophalen. Anders vervuil je toch maar je model. Als je te specifieke queries maakt voor elk scherm geraak je vroeg of laat in de problemen omdat je door het bos de bomen niet meer ziet. Voorts zou ik geen query in een loop uitvoeren maar proberen om alle info in 1 query op te halen.

Vandaar dat ik zei dat je het per project / situatie moet bekijken. Had het misschien niet geheel juist verwoord. :)

Jerre Muesli

Legacy Member
Nee nee je had het goed verwoord hoor, ik wou gewoon ook effe reageren ;)

bealzebub

Legacy Member
Omdat er duidelijk nogal wat verwarring is omtrent wat een model juist is en wat het mag doen, zou ik je aanraden van er eens een boek van een MVC framework zoals Symfony bij te nemen. Misschien zelfs nog beter één van Ruby on Rails, het zal leesbaarder en verstaanbaarder zijn zelfs al ken je geen fluit van de taal. Lees bv eens door het modelgedeelte op Ruby on Rails Guides
Daarmee weet je direct wat er juist allemaal thuishoort in het model.

En ja, je mag in één model data van andere modellen gaan afhalen. Je model encapsulate de functionaliteit van je objecten. Als daar gerelateerde objecten aanhangen, dan mag je dat via het model opvragen.

Nu, in verband met je meerdere queries dan. Frameworks lossen dat probleem dus grotendeels op door de problematiek van jouw schouders te nemen (gow, de goeie toch). Wat doen ze eigenlijk? Voor de lifetime cycle van je method call gaan ze ipv ieder keer gewoon een query per class te doen (Blog, Comment, &#8230;), gaan ze die opsparen in promises of iets gelijkaardig. Je kan het vergelijken met hetvolgende: als je een complex recept uit een kookboek wil klaarmaken, dan ga je de ingrediënten eerst uithalen en klaarzetten, dan eens kijken wat de meest efficiënte manier van werken is en dan pas beginnen koken.

Als je het MVC concept nie goe snapt, probeer dan echt niet het warm water uit te vinden, neem er een MVC framework (en documentatie ervan) bij en zorg dat je het onder de knie krijgt. Het begrip van de nuts en bolts komt later wel. En maak je niet al te veel zorgen over wat de meest efficiënte query is en of je er niet twee of drie te veel doet. Dat kun je echt onder het "develop first, optimize later" principe laten vallen. Je kan toch niet weten waar er een bottleneck zal zitten tot je effectieve benchmarking en statistieken van je app kan trekken.

VinceVe

Legacy Member
KenSpectre zei:
Nog een andere manier die wij op het werk bv gebruiken is Doctrine. Deze haalt practisch alles voor je op als je je database opstelt volgens hun regels.
Doctrine URL
Echter zou ik hier nog even mee wachten.

Indien je nog vragen hebt stel ze gerust. Ik hoop dat het een beetje duidelijk is.

Vergeef me de PHP code, ik ben gewoon om te werken met Zend :)

Je verward hier de model laag met de data mapping laag.
Bij Doctrine komt het erop neer dat je data classes hebt gedefinieerd, en dat deze alleen maar de data omvatten, geen queries. De laag hierboven komen dan de queries, zodat deze afgesplitst zijn van je dataklasse. Mijn structuur is als dit:

-- Frontend | webservice --
-- business logic --
-- Query laag --
-- Data Mapping laag --
-- Database --

Met deze structuur splits ik dus ook mijn business logic uit mijn Controller en kan ik deze hergebruiken, handig bvb voor een website waar logic nodig is, en je webservice.

bealzebub

Legacy Member
Idd, fat models, slim controllers. Alhoewel je je ook vragen moet stellen bij hele vette modellen. Hetzelfde geldt eigenlijk voor alles wat met programmeren te maken heeft: geteste, begrijpbare en managable code die zichzelf niet herhaalt. Da's de kunst.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan