2008年8月14日星期四

Re: [fw-mvc] Model Validation

Hi Matthew,

perhaps I should have had a longer answer before...

Well, I don't really understand why such an approach would lead
to problems.
And I assume we are talking about models as a representation of
objects relevant to your problem domain, independent of things like
persistance.

If you have more than one model handling the same logical data/type,
you would not be DRY anymore, you would have to put it in every model.

Therefore:
Why not use "logical type", like Birthdate, Address, even Username?
If you create a logical object for every one of it you can handle
all semantic validation and even formatting in one place.

So, instead of having to check a date in every model that uses a date
you would have to create a Date object and send it to the model, or any
other component of your software, if it is validated.
Then it simply doesn't matter if it's MVC, a server component or
something else, it is always a valid Date object.

Virtually anything that has "relevance" to your domain and need to be
checked semantically should be a logical data object (type).

Saving the person's data could then look like this (simplified):

$name = new Username ($firstname, $mi, $lastname);
$birthdate = new Birthdate ($year, $month, $day);
$address = new Address($country, $city, ...);
...
$person = new Person();
$person->save($name, $birthdate, $address, ...);

I left out the exception handling, you can throw it in the class
Birthdate or check it in the app [if ($birthdate->isValid()], that
depends on your needs.
But the class Person has not to check this anymore, it will never get
polluted by unfiltered input. And beside that, it would violate SRP by
letting a model check, validate, filter, save and retreive data.

Now e.g. birthdate is handled in ONE place of your application, has all
required rules and constraints and simply knows ITSELF if it is valid or
not.
Clearly DRY and useable everywhere.

Often it's the old problem of not understanding models as that what they
are: *Models* of your problems and their possible solutions, done with
software.

But perhaps I missed the clear view of the problems you faced...
;-)

Matthew Weier O'Phinney wrote:
> -- Nino Martincevic <don@zampano.com> wrote
> (on Thursday, 14 August 2008, 06:11 PM +0200):
>>> Is there an even DRYer solution to the error handling problem? I
>>> suppose it depends on the specific needs of the application, which
>>> would mean there isn't really a right answer :)
>> One approach for layered architectures is that any layer below should
>> receive only already valid(ated) data and has no need to check it again.
>> So you would do your validation before you pass it to the model.
>
> This is how I operated for quite a while. However, this falls apart when
> you start building models that you not only use in your MVC apps, but
> which you also attach to the various Server components of ZF -- all of a
> sudden, you're exposing the model to direct, unfiltered input.
>
> You _could_ create a wrapper over the model for use as a service, but
> then you're duplicating the input filtering object between that wrapper
> and your MVC app that uses the model. If you then decide to just use
> that wrapper from your MVC app.. well, you might as well have just
> attached the input filter to your model to begin with.
>
> One thing I've started playing with is attaching my forms to my models.
> They then serve two purposes: input filtering, and a GUI representation
> of the model as a form. Just another thing to play with. :)
>

没有评论: