Reputation: 13310
When validating a domain entity, is it better to validate the values as they are set, or all at once with a validator (such as in Symfony2) later on?
For example:
Option 1. Validate while being set
public function setEmail($email)
{
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new EntityException('The specified email address ' . $email . ' is invalid.');
}
$this->_email = $email;
return $this;
}
Option 2. Validate later...
$user = new UserEntity();
$user->setEmail('[email protected]');
$validator = new Validator();
$validator->validate($user);
Option 3. Both of the above (although seems a little redundant and not worth the overhead).
I know that the first one probably makes for more airtight entities, but the second one makes for more user friendly error handling.
Also, the second option seems easier to configure and maintain...as I don't have to adjust the setters, and I can centralize my validation logic to a single class.
What it boils down to...
So basically, it sounds like Option 2 is what I WANT to do, but feel like sacrificing the airtight-ness of the entity (for example, if I forget to run the entity through the validator), might be stupid.
Upvotes: 2
Views: 1022
Reputation: 6202
Single Responsibility Principle
The best is to have all necessary validations in a separated layer. With that will be easier to maintain and test the validators. Also easier to validate data across your application.
Don't Repeat Yourself
You don't have to call validate() for each entity.
All you have to do is to implement the validation on your repository layer or service layer if you have one.
$user = new User();
// [...]
$user->setEmail('myinvalidemail#blah,com');
$repository->save($user);
So in your user's repository
UserRepository extends AbstractRepository {}
And the common validation for all entities:
abstract class AbstractRepository {
public function save($entity) {
$validator = // Get your validator based on the entity's name or something else
$validator->validate($entity); // Throws exceptions or flag the fields for future use
// Now save it...
}
}
Upvotes: 1
Reputation:
There are doubtless going to be situations where validation is unnecessary at the application level (i.e., you know you are working with valid data at a particular point). Although there's nothing wrong with applying validation in these cases, it's certainly superfluous.
In addition, you might find yourself in a scenario where you want to perform a "mass validation" of incoming data. This would likely apply more to a service or to custom-implemented forms where you don't have e.g., Symfony's form validation framework to fall back on.
These would tend to indicate that Option 2 is the more desirable way to go, perhaps with caveat that the validator should be invoked automatically when attempting to persist the object (e.g., during the model's pre-save event; I'm not familiar with Doctrine 2 yet, but Doctrine 1.2 does have its own validation framework that can accomplish this).
Having invalid data is surely never a desirable scenario, but so long as you can be assured that invalid data are not persisted, this gives you the freedom to trust that any data you pull from the database are valid (note that I say "valid" here, not "trustworthy"!).
Upvotes: 2