Page 1 of 1
Front (actually, Page) Controller design
Posted: Sun Sep 25, 2005 8:04 am
by Nathaniel
Hey guys,
McGruff's points in the OOP vs. Procedural threads finally convinced me to try TDD. I think I'm addicted to seeing that green bar now. I don't know how I lived without TDD... but anyway.
I believe I've done a relatively good job keeping tasks seperate, in their own objects, writing tests, and then code to pass the tests, but I'm stuck on my front controller on my Lyrics website project (which I've been working on for several weeks now... I didn't steal your idea, vchris.

).
That it's procedural is one problem, but also that I'm not sure how I could test the page itself is another. I plan to write tests for all of the components in the page before writing the cpmponents themselves.
An example URL which would be passed into this script is
example.com/artist_name/album_name/song_name/. My OrganizeResourcesRequest uses several classes for validating / formatting... so $request->artist() would return 'artist name'. Then my RetrieveArtist object would "SELECT ... WHERE LOWER(name) = $name". Makes for nice URLs.
Code: Select all
<?PHP
# Lyrics / includes / assembler.php
# Nathaniel Jones
# September 25th, 2005
include('common.php');
$request =& new OrganizeResourcesRequest($_GET['url']); //unit tested, works great
$overall =& new TemplateFile('overall.html');
$failure =& new TemplateFile('404.html'); // will be an extended class which sets 404 header...
// AssembleArtist, AssembleAlbum, AssembleSong extend AssembleModule
if ( $request->albumRequested() == false )
{
$artist = new AssembleArtist($request->artist());
$artist->moduleFailureRecovery($failure);
$overall->assign('titles', $artist->assembledTitles());
$overall->assign('content', $artist->assembledContent());
}
else if ( $request->songRequested() == false )
{
$album = new AssembleAlbum($request->artist(), $request->album());
$album->moduleFailureRecovery($failure);
$overall->assign('titles', $album->assembledTitles());
$overall->assign('content', $album->assembledContent());
}
else
{
$song = new AssembleSong($request->artist(), $request->album(), $request->song());
$song->moduleFailureRecovery($failure);
$overall->assign('titles', $song->assembledTitles());
$overall->assign('content', $song->assembledContent());
}
$overall->display();
exit;
?>
If there is anything that needs changing (I'm sure there is), or an article relating to what I want to do (I need PoEAA for Christmas), I'm eager to learn.
- Nathaniel
Posted: Sun Sep 25, 2005 8:09 am
by Charles256
that's it.i give up.what the hell does TDD stand for?
Posted: Sun Sep 25, 2005 8:14 am
by feyd
Test Driven Design or Test Driven Development
most often the latter..
Posted: Sun Sep 25, 2005 8:19 am
by patrikG
tdd =
test driven development. For PHP this involves third-party applications such as
SimpleTest or
PHPUnit.
Posted: Sun Sep 25, 2005 8:21 am
by Maugrim_The_Reaper
At the risk of posting Sitepoint references...
There's an interesting take on FC at
http://www.sitepoint.com/forums/showthread.php?t=184548 . Might give you some insight on thoughts in the area. Please ignore the naggling over the purity of the example as a FrontController - Sitepoint authors can argue for days on the topic of maintaining absolutely pure unmodified patterns...

I found it fairly interesting at least... The topic title is a little misleading - it only addresses the C in MVC.
Your code above looks fine to me. It may not necessarily be a Front Controller pattern per se - but who cares about that! It looks good, it works - tell the pattern purists to take a leap...

Re: Front Controller design
Posted: Sun Sep 25, 2005 10:09 am
by Buddha443556
Nathaniel wrote:That it's procedural is one problem, but also that I'm not sure how I could test the page itself is another. I plan to write tests for all of the components in the page before writing the cpmponents themselves.
I kind of wonder how you have code and no tests. If your not testing first then it's not TDD. One of the benefit of TDD is 100% test coverage. Is your intention to rewrite your entire script or just apply unit testing?
Maugrim_The_Reaper wrote:Sitepoint authors can argue for days on the topic of maintaining absolutely pure unmodified patterns...
I sometimes wonder if they just skipped the Preface and Narratives of PoEAA when they read it.

Re: Front Controller design
Posted: Sun Sep 25, 2005 11:43 am
by Nathaniel
Buddha443556 wrote:Nathaniel wrote:That it's procedural is one problem, but also that I'm not sure how I could test the page itself is another. I plan to write tests for all of the components in the page before writing the cpmponents themselves.
I kind of wonder how you have code and no tests. If your not testing first then it's not TDD. One of the benefit of TDD is 100% test coverage. Is your intention to rewrite your entire script or just apply unit testing?

I wasn't sure how to create a unit test for the code I posted (because it is procedural), so I just quickly wrote out what it had to do, then programmed it. It didn't take long. If there is a way I should be doing what I need with an object, I'll write a test for it, then the object, and scratch the code I posted above. If there is a way I should be testing it, even as a procedural script, then I'll write the test and code to the test from scratch.
That said, I think using an object would be making things more complicated, and since my code works fine and is relatively simple (uses unit tested components and 3 if statements), I think I'll just leave it alone.
Re: Front Controller design
Posted: Sun Sep 25, 2005 1:14 pm
by Buddha443556
Nathaniel wrote:I wasn't sure how to create a unit test for the code I posted (because it is procedural), so I just quickly wrote out what it had to do, then programmed it. It didn't take long. If there is a way I should be doing what I need with an object, I'll write a test for it, then the object, and scratch the code I posted above. If there is a way I should be testing it, even as a procedural script, then I'll write the test and code to the test from scratch.
Looks like you have a web handler, OrganizeResourcesRequest()? Seem to be processing the request data anyway. Probably just need a Dispatcher. The front controller is dependent somewhat on the HTTP server (and PHP which does a lot of the dirty work) for input by creating a dispatcher you'll be able to automate the testing.
PoEAA wrote:Rob Mee showed me an interesting variation of Front Controller using a two stage Web handler separated into a degenerate Web handler and a dispatcher. The degenerate Web handler pulls the basic data out of the http parameters and hands it to the dispatcher in such a way that the dispatcher is completely independent of the Web server framework. This makes testing easier because test code can drive the dispatcher directly without having to run in a Web server.
Microsoft is another good source for pattern information:
Front Controller Notice the Testing Consideration section.
Re: Front Controller design
Posted: Sun Sep 25, 2005 6:33 pm
by McGruff
Nathaniel wrote:McGruff's points in the OOP vs. Procedural threads finally convinced me to try TDD. I think I'm addicted to seeing that green bar now. I don't know how I lived without TDD... but anyway.
Great! I've manged to test-infect someone
I think that's a PageController rather than a FrontController. The two patterns are both input controllers ie they receive user input, do some stuff and construct a response (or rather ask the response to build itself). Uniquely, FrontControllers also identify the request type and dispatch the request to something which can handle it. With FrontController, you'd tend to aim all requests at a single file (although you can have multiple FrontControllers) whereas, with PageController, apache or etc would route requests to individual PageControllers - broadly speaking one for each type of site page (eg "view posts").
Strictly speaking, there are almost always a range of possible pages per request type (if you tried to view a topic in the moderators forum you'd get an access denied page) so it's more correct to say that PageControllers map one to one with request types and one to many with possible responses.
Both patterns are valid options: I can't really think of a good reason to choose one over the other. The
Wact Wiki is worth a read for more info.
I think PageControllers as brief snippets of procedural code are fine. You can't avoid a few lines to kick everything off. You can test this in a web test case using the Simple Test web tester which allows you to make various assertions about page content - check out the docs for more info.
assertTitle($title) Pass if title is an exact match
assertWantedPattern($pattern) A Perl pattern match against the page content
assertNoUnwantedPattern($pattern) A Perl pattern match to not find content
assertWantedText($text) Pass if matches visible and "alt" text
assertNoUnwantedText($text) Pass if doesn't match visible and "alt" text
assertLink($label) Pass if a link with this text is present
assertNoLink($label) Pass if no link with this text is present
assertLinkById($id) Pass if a link with this id attribute is present
assertNoLinkById($id) Pass if no link with this id attribute is present
assertField($name, $value) Pass if an input tag with this name has this value
assertFieldById($id, $value) Pass if an input tag with this id has this value
assertResponse($codes) Pass if HTTP response matches this list
assertMime($types) Pass if MIME type is in this list
assertAuthentication($protocol) Pass if the current challenge is this protocol
assertNoAuthentication() Pass if there is no current challenge
assertRealm($name) Pass if the current challenge realm matches
assertHeader($header, $content) Pass if a header was fetched matching this value
assertNoUnwantedHeader($header) Pass if a header was not fetched
assertHeaderPattern($header, $pattern) Pass if a header was fetched matching this Perl regex
assertCookie($name, $value) Pass if there is currently a matching cookie
assertNoCookie($name) Pass if there is currently no cookie of this name
Posted: Sun Sep 25, 2005 7:33 pm
by McGruff
Maugrim_The_Reaper wrote:At the risk of posting Sitepoint references..
No problem here. They've got a great advanced php board - I often recommend it myself.
Posted: Mon Sep 26, 2005 3:53 pm
by Nathaniel
Thanks, McGruff. Reading up on Page Controllers instead of Front Controllers made understanding what I was doing a lot easier...

I look forward to getting PoEAA.
For anybody running across this thread later with similar concerns to mine: The
Page Controller information in the MSDN library (it's in the same directory as the Front Controller link Buddha posted - thanks, Buddha).
- Nathaniel, who's page controller is working perfectly