I’m interested in DDD (Domain Driven Design) in the last days, but I can’t figure out the responsibilities of who creates and validates the entities. Ill break this questions to cover different scenarios.
-
Regular entity (Possibly with value object). As an example lets take a user who is identified by Email. I have a UserFactory that receives an array of data (possibly from form POST), and return me a new UserEntity. Should the factory validate the integrity of the data (ex: string given as Email is a real email, passwords in password field 1 and field2 match and etc)? Should the factory validate that no such user exists already (we dont want to register two users with the same email)? If yes should it do it my itself or using the UserRepository?
-
Aggregate entity. Lets assume we have a Post entity and Comments entities. I want to get post 12 with all its comments, so I do something like
$post = $postRepository->getById(12);
How getById should be implemented? like this:
public function getById($id) {
$postData = $this->magicFetchFromDB($id);
$comments = (new CommentRepository())->getForPost(12);
return new PostEntity($postData, $comments);
}
Or maybe the post responsible for lazy creating its comments, something like:
class PostEntity {
public function getComments() {
if(is_null($this->_comments)) $this->_comments = (new CommentRepository())->getForPost($this->_id);
return $this->_comments;
}
}
?
I’m very lost here and there is not enough information with examples for DDD in PHP, so any help will be appreciated!
Thank you a lot,
skwee.
The factory should only care about creating entities. I personally preferr to put validation both in my views and in the model layer. I’d use some library like jQuery’s validation plugin to make some essential validation on the client side (like checking if required fields have data). And then do the “hardcore” validation on the model.
I do this is by using a simple BaseEntity abstract class which all entities extend, and since you asked for an example, here it is:
You could also make use of a static helper class with some basic validation methods:
Many argue against static methods because they can break unit tests, but in this case they are pretty basic and they don’t have external dependencies, thus making them “safer”.
When it comes to checking for already existing entities you can do this by querying your DB to see if the entity is already there before adding/updating, or (this is how I like to do it) you could add a
uniqueindex to those columns that can’t be repeated in the DB, and then wrap the create or update queries in a try-catch block (the query will throw a unique constraint violation, if two users have same e-mail for example) and then show the proper error messageOn your last question it comes down to a matter of preference. If your DB will get a million hits in 1 minute, then it’s probably better to use lazy loading to avoid fetching unnecesary data until it’s needed. But if your database is relatively small you could perfectly use eager loading without sacrificing too much performance.
Again, this is a matter of personal preference.
hope some of this rambling makes sense, cheers!