I am going to assume you need validation for persistence.
Not only View, but Model should not handle validation either. During my days in IT I realized DDD is one of the ways to ensure you are actually doing things correctly, ie. classes are actually responsible for what they should be.
When following Domain-Driven design, your models include your business logic, and that is it. But they do not include validation, why not?
Let's assume you are already as far that you are using Data Mapper
instead of Active Record
to persist your domain layer. But still, you want models to be validated, so you add the validation to your Model.
interface Validation
{
public function validate();
}
class ConcreteModel extends MyModel implements Validation
{
public function validate() { // the validation logic goes here }
}
The validation logic ensures, you can correctly insert the model into your MySQL database... A few months go by and you decide, you wanna store your Models in noSQL databases as well, databases, which require different validation rules than MySQL.
But you have a problem, you have only 1 validation method, but need to validate a Model
in 2 different ways.
The models should do what they are responsible to do, they should take care of your business logic and do it well. Validation is tied to persistence, not business logic, hence validation does not belong to a model.
You should create Validator
s instead, which will take a model to validate in their constructor as a parameter, implement the Validation
interface and use these Validator
s to validate your objects.
interface Validation
{
public function validate();
}
class MySQLConcreteModelValidator implements Validation
{
public function __construct(ConcreteModel $model) { }
public function validate()
{
// you validate your model here
}
}
class RedisConcreteModelValidator implements Validation
{
public function __construct(ConcreteModel $model) { }
public function validate()
{
// you validate your model with different set of rules here
}
}
If at any time in the future decide you want to add another validation method for another persistence layer (because you decided Redis and MySQL are not the way to go anymore), you will just create another Validator
and use your IoC
container to get the right instance based on your config
.