Model or controller

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Model or controller

Post by alex.barylski »

Similar in nature to my other thread:

viewtopic.php?t=75264

This time I ask. Suppose I have a model which pulls on a table which contains several fields, one of which is a timestamp (I convert all date/time to UNIX timestamp when storing in DB).

That date needs:

1) To be converted to a format according to user's locale settings
2) To be converted from a human friendly format to a timestamp

#1 could be done in the view, but would require the View to have access to the users locale object. Alternatively, it could be done in the model (where in my case it currently is) which at least has the benefit of formatting the date in human readable fashion no matter where the Model is used (severl other views use it).

Both of these instances have the one drawback. The make the model/view depedent upon what I would consider application specific functionality - the locale object.

For this reason, I am tempted to refactor the formatting code from the DB and put it in the controllers instead. Likewise, instead of passing the date as a formatted string, I would convert the string (using the locale object) into a timestamp before passing that data to the Model.

The problem with using the controller in this regard is that I loose some application level reuse at the gain of a more generic mode/view class. Under the context of my application I get more code reuse when it's in the model, then I do if it's in the controller.

If I have 2 controllers which use my model, then each of those two controllers needs to format/convert the date from one format to the other. One before sending the date to the model and one before sending a timestamp to the view for rendering.

If I have this logic inside my model, the anytime I call that model the date is formatted for me *BUT* again this comes at the expense of having to somehow have the model be aware of a locale object, which is initialized with user details. If the model is now depenendent upon the locale object, it looses it's re-usability in other projects, if the next application doesn't need locale information, we have code which serves no purpose.

I have considered several techniques to minimize the dependency:

1) Use DI to avoid conrete dependency.
2) Access the registry from within the model so we can access the locale object - which now creates two dependecies (one on the registry and one on locale).

Should I refactor the code for formatting into the controllers and just accept the loss of code reuse at the expense of more logic code or something entirely different???

Cheers :)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Model. It has nothing to do with controlling application flow, nothing to do with view, everything to do with application logic.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

Okay I have to ask now, why are you even testing your controllers? Something smells here, although without seeing the code I cannot really point anything out specifically.

Typically what you are describing is integration testing, where you are testing the end result of several components interaction. Since controllers, models and views generally should not be Unit Tested since they are application specific, this is a tough one to follow. One would typically only test the underlying library and as I mentioned, never unit test anything application specific. For example, why not abstract the local formatter into it's own respective object instead and test that?

I'll leave this one to the testing experts lurking around.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Model or controller

Post by Christopher »

Hockey wrote:Both of these instances have the one drawback. The make the model/view dependent upon what I would consider application specific functionality - the locale object.
That's not a drawback ... it is just a fact. You have a common dependency, nothing wrong with that. You possibly have a cross-cutting concern. In that case DI might be appropriate. But adding stuff to your controllers is heading the wrong direction.
(#10850)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Thanks for the feedback guys. I decided to go forward with changing my static models into objects, using a service locator to access models inside my controllers. In the process I also implemented a locale object accessible in my models.

Cheers :)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Typically what you are describing is integration testing, where you are testing the end result of several components interaction. Since controllers, models and views generally should not be Unit Tested since they are application specific, this is a tough one to follow. One would typically only test the underlying library and as I mentioned, never unit test anything application specific. For example, why not abstract the local formatter into it's own respective object instead and test that?
I'd actually disagree here. The problem with not testing controllers, models and views (obviously for very limited content) is that it's very hard to drill down into an application when an acceptance test goes downhill. Also who says you can't apply TDD/BDD to them either? The only problem here is what Hockey is starting to note - MVC applications use a whole slew of objects and you need to have some system for mocking and testing which is very likely unsupported out of the box by any framework or unit testing system. At the moment I'm using a custom built framework, in conjunction with SimpleTest, to TDD controllers - the trick is in boiling down all the controller setup into a few terse steps - it's not mocking entirely since these use real objects (most frameworks are not TDD'd and so mocking can be pretty difficult if not impossible - real objects for stuff like Requests/Response/Routers is just an easier path). Another things, motivated by hard to mock controllers, I know Travis Swicegood is looking into is doing class replacement in a new process ( a bit like how PHPMutagen works ) on objects you can't substitute in.

Once you piece together something, TDD for MVC is a fairly intuitive affair. Mock the models, have an API grammer for dispatching requests, detect responses/redirects, make your assertions, and bingo. The model mocking is probably key - esp. if the Response depends on it (easy to figure out an assertion then ;)). Testing Controllers or Controllers+View (the Response object, or final output) is a difficult decision - I prefer the Response object where possible.

There is undoubtedly a question of whether application specific code is worth testing. I find it pays to do it - less for the testing, than the benefits of TDD (design). I find it's easier to piece how a controller's action should work using TDD or BDD, than coding on the fly without a safety net.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

Maugrim_The_Reaper wrote:There is undoubtedly a question of whether application specific code is worth testing.
Okay okay, thats kind of where I was heading.

When I think of testing an application integration testing comes to mind. With the unit tests for the underlying library and the integration tests of the application would pretty much tell you exactly when a portion of your application was failing. All I want to know is when Form A is submitted, Database B is updated correctly; I don't care about the output generated.

Perhaps if I was working for NASA I would have a slew of integration and unit tests, but I think for about 99.9% projects unit testing your models/views/and controllers is mad :)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Important distinction though - I use TDD to design a controller; that it has tests afterwards is coincidental ;). I still have acceptance tests (using selenium usually) to act as the relying tests.
Post Reply