(on Tuesday, 09 December 2008, 12:38 PM -0800):
> > I recently complained (i.e. ranted) on the topic over at
> > http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html
>
> Beautiful article.
>
> I get where you're coming from Most controller logic belongs to the domain
> model so we created a domain model for this type of stuff, but the standard
> everywhere I looked was to have "control" logic in the controller - what
> about form and form validation etc? This is handled in the controller at the
> moment. If I were to validate forms in the controller and validate data in
> the model ( to keep it skinny), I'd be validating all over the place - so
> I'd move my form into the Domain model.
>
> Which again works as a proxy... which in this case may not be that bad...
> don't know not going to delve too deep into that one.
I'm going to pipe in here about this particular topic.
Zend_Form's design is such that it can act as a value object, a
validation chain, or as a view representation. As such, I've been
attaching forms to my model classes. This allows me two things:
* Ability to keep all validation logic self-contained in the model,
leaving me with fat models and skinny controllers.
* Ability to provide one or more form representations of my model.
How does the first work? Well, in my controller, I now am checking if
operations in my model succeed, rather than validating a form, injecting
data into the model, checking to see if an operation succeeds, etc. It
makes the logic much simpler:
if (!$id = $this->model->insertSuchAndSuch($request->getPost())) {
$this->view->model = $this->model;
return;
}
$this->_redirect($this->_helper->url(array(
'action' => 'view', 'id' => $id
));
As for the second, consider the related view script:
$form = $this->model->getSuchAndSuchForm();
// ...
// maybe manipulate my decorators, as the view is the right place to
// do that
// ...
echo $form;
Now, all that aside... you can do all of this using Zend_Db_Table as
your base model as well. I choose not to, but I totally understand your
arguments.
> RE Views should be able to fetch their own data - I TOTALLY agree with you -
> In the old framework we were using that we had created, the view had access
> to a local model locator which the controller is also free to use.
>
> Model locator knew how to create models and was the gateway to accessing
> models. What about forms? currently forms are fed into the view from the
> controller. Will views be able to fetch their own forms also? if so, does it
> work the same way as the model? being used by the view and the controller?
You can certainly write all of the above using ZF as well. And if your
models has-a forms, then you already have access to your forms. Win!
> > I generally prefer to avoid the inherited-from route. It's appropriate if
> > all you're doing is data > access (not the real use of a Model) but it
> > tightens the coupling between your Models and the
> > underlying framework. Ideally Models are unaware of the framework, the
> > acid test being able > to quickly port them from one framework to another
> > with little to no change.
>
> But say that you've developed the model specifically for use with the
> framework and had simple requirements such as "getList()" - will it still be
> wrong then?
>
> I've always seen the domain model as something to develop toward as your
> requirements increase instead of using it as a starting point.
I'm in agreement with you here for the most part. It' pretty trivial to
refactor to use a domain model that utilizes a TDG as a data provider.
When you're trying to build quickly and prototyping, it often doesn't
make sense to build a full blown domain model... because you often don't
fully understand the domain quite yet.
However, there *are* other patterns that still offer abstraction while
staying compatible with domain models. I use the Table Module pattern
quite a bit myself -- in part because it provides easy testing
capabilities (inject a dummy object when testing, and have that dummy
object act in place of your TDG). It's also trivial in such a situation
to have __call() proxy to your TDG, which gives you the benefits of
rapid prototyping while simultaneously giving you the flexibility to
morph the implementation easily in the future.
I think you have some valid arguments for using TDG as a model. I think
there are some equally valid arguments against it. The point, however,
which you also point out, is to choose wisely.
--
Matthew Weier O'Phinney
Software Architect | matthew@zend.com
Zend Framework | http://framework.zend.com/
没有评论:
发表评论