|
Best practices in a thin-controller application: msg#00098php.zend.framework.mvc
Hello! (I apologize if this gets sent out more than once...my other email address, Adam.Jensen-gkxvx00wFtQ@xxxxxxxxxxxxxxxx, does not seem to be able to post to the lists anymore.) I'm trying to rethink some of my controller code due to Bill Karwin's "ActiveRecord does not suck" post, and I'm having some trouble figuring out where to put what. Here's an example. Say we're building an application for tracking the travel schedules of employees. There are two kinds of domain objects: Trips and Destinations. Every Destination has a Trip, and every Trip has many Destinations. Users interact with the domain on the Trip level…they can list, view, add, edit, and delete Trips, adding and/or removing Destinations in the process. Each of these is represented in the controller by an appropriately-named action. So, at this point we have the following classes in the library: * Travel_Trip * Travel_Trip_Destination * Travel_TripsController The first problem arises when I try to write the "list" action. Each of the domain objects listed above represents a single entity…none of the indicated classes is designed to represent a collection. So we need to add another class for managing the collection: * Travel_Trip_Collection Feels a little strange to me, as I've always considered the collection to be the root of the domain, at least when treating tables and domain models as though they were the same thing. Is there a better way? The other problem here is that, while the Travel_Trip_Collection represents the total collection of Trips in the system, it will need to return smaller collections of trips in response to particular method calls. For instance, Travel_Trip_Collection::fetchAllByCountry('FR') will need to return a collection containing all trips to France. It doesn't seem right to use the same collection for this, so we add another class: * Travel_Trip_List The semantics at this point are confusing, because Collection is sort of like a table, whereas List is sort of like a rowset...but their names don't clearly imply this fact. Moving on, my next problem is handling user errors in the remaining methods. Take a look at this: [code] public function viewAction() { try { $this->view->trip = new Travel_Trip($this->_getParam('id', null)); } catch (Travel_Trip_Exception_NotFound $e) { throw new Zend_Controller_Action_Exception('Requested trip not found.', 404); } } [/code] This works, but seems a little inappropriate on a couple of levels. First, I don't think exceptions were meant to be used this way; they're functioning almost like goto statements, and that makes me uncomfortable. Second, we don't get much feedback from the model as to what exactly the problem is with the user's input. It could be one of several things: * The user did not provide an ID parameter. * The user provided an invalid ID parameter. * The provided ID number is valid, but does not correspond to any Trip in the Collection. In the past I've always tried to do something slightly different for each of these circumstances, so that the user always knows what was wrong about his/her request. In order to do this with domain model exceptions (as above), I'd need three separate exception subclasses, right? I suppose the other option for error handling is to have the model keep track of its own error state…but that introduces extra controller code for checking the error state, a la… [code] public function viewAction() { $this->view->trip = new Travel_Trip($this->_getParam('id', null)); if ($this->view->trip->failed == Travel_Trip::NOTFOUND) { throw new Zend_Controller_Action_Exception('Not found', 404); } // check for other error codes as well… } [/code] That's a mouthful; I think I like the exceptions better :) Anyway, I'm sorry that my questions are not more specific; I'm really just looking for some clarification as to how the domain layer is supposed to be implemented, as it's not something I've had much opportunity to study. Does it look like I'm on the right track, or is there something I'm missing? Thanks! Adam Jensen, Zend Certified Engineer Web Development UNT International jazzslider-Re5JQEeQqe8AvxtiuMwx3w@xxxxxxxxxxxxxxxx http://www.international.unt.edu |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Question about setControllerDirectory: 00098, David G. |
|---|---|
| Next by Date: | Re: Question about setControllerDirectory: 00098, Nguyen Kha |
| Previous by Thread: | Question about setControllerDirectoryi: 00098, David G. |
| Next by Thread: | Re: Best practices in a thin-controller application: 00098, Nino Martincevic |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |