I want to use MVC pattern in my PHP project. I also want to use Dao-Service pattern for Model layer since it makes database engines easily interchangeable and keeps business logic out of DB interaction.
Now, I heard that validation should happen in Model layer since Controllers are only responsible for transporting data. That's pretty reasonable.
Should it, however, be implemented in Service layer, or entities themselves?
Approach 1: validation in entities
class Post extends Entity
{
protected $title;
public function getTitle()
{
return $this->title;
}
public function setTitle($newTitle)
{
if (strlen($newTitle) == 0)
throw new ValidationException('Title cannot be empty.');
$this->title = $newTitle;
}
}
class PostService
{
public static function saveOrUpdate(Post $post)
{
PostDao::saveOrUpdate($post);
}
}
Pros:
- I know immediately if I do something wrong,
- everything is in one place, which seems like a good thing.
Cons:
- lots of boilerplate code due to fancy setters and getters,
- adds some business logic to entity, which seems like a bad thing (especially if validation is very complex - e.g. needs to query database / other services),
- serializing and deserializing might become difficult.
Approach 2: validation in service
class Post extends Entity
{
public $title;
}
class PostService
{
public static function saveOrUpdate(Post $post)
{
if (strlen($post->title) == 0)
throw new ValidationException('Title cannot be empty.');
PostDao::saveOrUpdate($post);
}
}
Pros:
- keeps business logic to service, which seems like a good thing,
- boilerplate is kept to minimum.
Cons:
- I don't know immediately when things go wrong and what did actually go wrong.
- I have no guarantee that validation will actually take place before saving it to database. An example: I have to save post in two routines, forget to use
PostService::saveOrUpdate
proxy in one of them and do it directly viaPostDao::saveOrUpdate
. Poof, validation doesn't take place in that routine and project's only hope are now unit tests or myself spotting it in the code. Thus, code is more difficult to maintain in this regard.
Do you have any hints, SO? Am I missing something? So far the project is on drawing board so I'm ready for anything.