Let's craft software solutions together. Contact me
Cover Image for Domain model purity and completeness

Domain model purity and completeness

Maybe you have never heard about domain model purity and completeness. However, they were present in almost every application you wrote.

Let’s say we have to develop a library management application. A member can be registered by introducing his name and ID:

public class Library {

  public void registerMember(String name, String id) {
    if (!Id.isValid(id)) {
      throw InvalidIdException();
    }
    // save member
  } 

}

As you see, we are validating the ID before saving the new member. In this case, we say domain model is complete, because all the needed logic to perform the operation belongs to the model itself.

What if before adding a member we need to check if he is already registered? To do so, we need to query the data source using a repository. For example, in controller layer:

@POST("/members")
public Response registerMember(String name, String id) {
  if (repository.existsMemberWithId(id)) {
    return Response.CONFLICT;
  }
  library.registerMember(name, id);
  //...
}

In this case, logic responsible of check if member is registered is outside the domain model (controller layer). Here, we say there is a domain logic fragmentation: we have logic both inside and outside the model. How could we solve this?

A possible solution could be simply passing as parameter the repository in the registerMember method.

public class Library {

  public void registerMember(String name, String id, Repository repo) {
    if (repo.existsMemberWithId(id)) {
      throw MemberAlreadyExistsException();
    }
    if (!Id.isValid(id)) {
      throw InvalidIdException();
    }
    // save member
  } 

}

This way, there is no logic fragmentation anymore, since all of it is inside the domain model. However, we are giving up the domain model purity.

We say a domain model is pure when it interacts just with other entities, value objects or primitive types. In this case, that is not happening since model (class Library) is interacting with components out of the model (repository).

So, the question is: what is more important, model purity or completeness?

In my opinion, we should choose purity over completeness. Domain logic, belonging to domain model, is, generally, the most relevant and complex. We should avoid make it even more complex adding external dependencies and making testing harder.