2008年12月9日星期二

Re: [fw-mvc] Another Model Design Thread

My main reason for wanting more abstraction is for easy unit testing,
I normally need my unit tests to run quickly ie without using a
database connection! So having a has-a relation in my model means I
can swap the table classes out for testing.

Matthew, the Table Module pattern is that similar to the way you built
buggapp and your dojo example?

2008/12/9 Matthew Weier O'Phinney <matthew@zend.com>:
> -- rvdavid <rvdavid@devproducts.com> wrote
> (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/
>
>

--
----------------------------------------------------------------------
[MuTe]
----------------------------------------------------------------------

没有评论: