[OOP] MVC: Volgorde aanroepen
Na nog wat verder te hebben gelezen over het MVC pattern, kan ik het allemaal even niet meer volgen. Vandaar dat ik de vraag heb of het volgende overzicht en naamgeving goed is:
1. De gebruiker komt op index.php/vbController/vbMethod;
2. In config.php wordt een view en database geselecteerd en in een global gezet;
3. In index.php wordt de FrontController aangeroepen;
4. De FrontController scheidt in de 'router' (naamgeving?) de link in de class 'vbController' en de methode 'vbMethod';
5. De router roept de dispatcher aan;
6. De dispatcher roept de juiste controller en methode aan;
7. In deze controller wordt de pagina 'gedirigeerd'. Andere classes (models) die nodig zijn worden aangemaakt, hierin worden bepaalde methodes aangeroepen. De nodige weergaves worden geplaatst in een globale view;
8. In index.php wordt de view 'gerenderd'. Dit gaat aan de hand van een template (smarty) met de naam van de controller en methode (vbController_vbMethod.tpl). Bestaat deze niet, dan wordt er een standaard template geladen.
Klopt het dat ik in deze acht stappen weergeef, hoe een 'request' vanaf de gebruiker een bepaalde weergave tot gevolg heeft?
Alvast bedankt!
Edit: Typo
Gewijzigd op 01/01/1970 01:00:00 door Tim
Ik heb alleen nog een beetje mijn twijfels over stap 5. Moet de router de dispatcher aanroepen, of zou het misschien een beter idee zijn om de router de combinatie van controller, method & argumenten weer terug te laten geven (als return value) aan de frontcontroller, welke dan vervolgens de dispatcher aanroept. Ik voel zelf meer voor die laatste volgorde, maar als je jouw volgorde kan verdedigen is dat ook prima natuurlijk.
Misschien is het nog handig om een globaal object beschikbaar te maken met verwijzingen naar helper-objecten. Bijvoorbeeld (weer terug) naar de router (je naamgeving klopt hier) zodat je die links voor je kan laten maken wanneer jij hem een controller-naam, method-naam en argumenten meegeeft. Je router weet immers het schema voor URL's, je templates in principe niet.
Als globaal object raad ik overigens het gebruik van een globale variabele af. Die dingen kan je veel te gemakkelijk "per ongeluk" overschijven, en je hebt niet zo veel controle erover. (ze zien er wel mooi uit in je code vind ik dan weer) Een register (oeh! design pattern alert! Google:registery pattern) zou je kunnen gebruiken, eventueel in combinatie met Singleton. (nog een design pattern, of naar mijn mening een anti-pattern maar goed)
Je kan ook een overkoepelend object maken, of je frontcontroller misbruiken, en iedere controller die je verder aanmaakt de instantie van je frontcontroller meegeven. Aan je frontcontroller hang je vervolgens je database, je view-object, je authorizatie-object (wat voor het ingelogd zijn zorgt) en al dan niet je model. Op die manier heb je overal waar nodig toegang tot die objecten, en hoef je niet naar enge dingen zoals singleton te grijpen.
(singleton is kut omdat het een oncontroleerbare globale state binnen je applicatie oplevert, en dat is iets waar je wel eens rekening mee zou moeten gaan houden, en dus is het niet leuk)
lees ook eens op: http://www.nosmarty.net/
De Dispatcher runt eigenlijk alles. De router is weer een tool om je urls, routes een extra dimensie te geven en dingen toe te voegen.
Het verzocht de routing van de uri/request naar de Applicatie/Page Controller en diens Action en eventuele parameters.
De Front controller maakt via het gehele verhaal een response object
Bestaande uit headers en een body, deze body is feitelijk je view in deze.
Er zijn veel meer soorten reponses, denk bijvoorbeeld ook aan een (mime) mail bericht.
In de config worden geen view en databases gezet.
Alleen variabelen. Zoals bijvoorbeeld database credentials. Etc...
In mijn eigen framework kan ik ook methods aanroepen vanuit de config.
Maar goed dat is niet de basis :-]
Singletons heb je nooit nodig!
Gewijzigd op 01/01/1970 01:00:00 door Lode
Bij mij zijn stappen 4 en 5 feitelijk 1... maar da's mijn oplossing.. opzich ziet het er prima uit!
Wat betreft MVC:
In mijn visie is het 'MVC'-model een hulpmiddel om zaken te structureren. Dit is met name handig wanneer er vele programmeurs werken aan dezelfde applicatie.
Je hoeft minder te klooien in andermans ontwikkelde code wat de kans op fouten sterk verminderd. Daarnaast kun je verschillende onderdelen los van elkaar verder ontwikkelen.
MVC heeft echter ook nadelen; zoals relatief veel meer overhead (data 'versturen' naar templates), en is (in mijn ogen) behoorlijk omslachtig op sommige punten zoals bij het uitwisselen van data tussen 'losstaande' objecten (iets waar bijv. Singletons vaak worden ingezet).
Gewijzigd op 01/01/1970 01:00:00 door Martijn Wieringa
En mag ik vragen welk framework je gebruikt dan Pholeron?
&core[view]=XXX&XXX[action]=YYY
Variabelen die door de 'core' worden ingelezen/weggeschreven gebruiken allemaal core[?], view specifieke variabelen in de URL gebruiken allemaal view[?]
Daarnaast gebruikt het framework zelf voor de meeste zaken geen OOP, maar binnen een view kun je vrij eenvoudig overschakelen naar een OOP aanpak. Elke view kan bijv. eenvoudig als class worden uitgewerkt..
Elke view retourneert een 'blok HTML code' (of REDIRECT de gebruiker) die door het framework binnen een template wordt geplaatst. Eventueel kan een view zelf CSS/JS files dynamisch toevoegen aan de output-buffer.
Bedankt!
Een file met html en overloaden framework functionaliteiten.
Hierdoor zijn templates overbodig geworden.
Wat weer een stuk snelheidswinst moet opleveren. Zeker als je een monster als smarty erbij zou hangen...
Ik kan daarnaast begrijpen dat een 'bakbeest' als Smarty de snelheid van een applicatie niet ten goede kan komen. Maar aangezien ik niet zo één, twee, drie een andere MVC-waardige oplossing kan bedenken, zal er altijd iets in die trant nodig zijn.
Uitzondering hierop kan het voorstel van jouw (Lode) zijn, tenminste, als je bedoelt wat ik denk dat je bedoelt.
Hoe de view is opgebouwd maakt eigenlijk voor MVC niet zoveel uit. Belangrijk is dat je vanuit je controller met je view kan praten zonder dat de controller hoeft te weten wat de toestand van de view is. Is de view bijvoorbeeld een template-parser, geladen met template, of een XML writer, de interface die je vanuit de controller gebruikt zou hetzelfde moeten zijn.
Nu is het in de praktijk niet altijd even handig om _al_ het presentatie-gebeuren in de view-laag te regelen, maarhet is prima mogelijk wanneer je gewoon gebruik maakt van objecten, ook voor datums & bedragen. Ik streef er zelf altijd naar om zoveel mogelijk presentatie-gerelateerde dingen uit mijn model en controller te halen, en in de view-laag te stoppen.
Over de indeling van de view-laag; Alleen een PHP bestandje includen is naar mijn idee niet genoeg. Je hebt ook nog logica nodig om standaard-elementen, zoals het raamwerk om je content heen, te verzorgen. Om dat in iedere weergave (een blogpost tonen is een andere weergave dan zoekresultaten bijv.) dezelfde code voor dat raamwerk te herhalen lijkt mij niet nodig, en zelfs onprettig wanneer je dat raamwerk nu juist wilt veranderen, ingewikkelder wilt maken.
Wat Lode overigens bedoelt is volgens mij dit: Je gebruikt gewoon PHP als template taal. Zo krijg je een heleboel mogelijkheden voorgeschoteld in een taal die je al gebruikt, en waarvoor alle vertaal-stappen heel dichtbij zijn. Een mogelijke implementatie
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
class Template_Native {
protected $_template_file;
protected $_variables = array();
public function __construct($template_file)
{
$this->_template_file = $template_file;
}
public function __set($key, $value)
{
$this->_variables[$key] = $value;
}
public function draw()
{
export($this->_variables);
include($this->_template_file);
}
}
?>
class Template_Native {
protected $_template_file;
protected $_variables = array();
public function __construct($template_file)
{
$this->_template_file = $template_file;
}
public function __set($key, $value)
{
$this->_variables[$key] = $value;
}
public function draw()
{
export($this->_variables);
include($this->_template_file);
}
}
?>
Template:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$view = new Template_Native('template.phtml');
$view->naam = 'Jelmer';
$view->draw();
?>
$view = new Template_Native('template.phtml');
$view->naam = 'Jelmer';
$view->draw();
?>
Gewijzigd op 01/01/1970 01:00:00 door Jelmer -
Ik heb er wel al eens over gepost hier.
Maar de zoekfunctie hier is zo brak....