It seems to me that there is a conflict between clean architecture and the recommendation not to use instanceof. Consider the following code:
class ParentEntity {
}
class AEntity extends ParentEntity {
List<Integer> entityIds;
}
class SaveUseCase {
IEntityRepository entityRepository;
void save(List<ParentEntity> list) {
entityRepository.save(list);
}
}
class EntityRepository implements IEntityRepository {
void save(List<ParentEntity> list) {
list.forEach(e -> {
if (e instanceOf AEntity)
validate((AEntity) e)
// Do save e in the database
...
}
}
void validate(AEntity a) {
List<ParentEntity> list = a.getEntityIds().stream().map(id -> get(id))
// Do some checking based on the value of list
...
}
ParentEntity get(int id) {
// Do get ParentEntity with identifier id from the database
...
}
}
The code has a usecase which calls the save method in the repository. The save method first checks the object only if the object is of type AEntity and then saves the object.
The problem is the use of instanceof in the save method of EntityRepository. If we want to prevent using instanceof, one solution is to make validate a method of ParentEntity and do the validation inside AEntity by overriding it. However, according to the clean architecture we have separated the entities and repositories, so inside entities we do not have access to get method of the repository, which is required for being able to do the validation.
The workaround to this is to put a reference to IEntityRepository (or at least something like GetUseCase) inside the entity so it can do the validation itself. But, this doesn't seem a very good idea to me, especially if we assume that validation is a logic of the repository and is there only to check, e.g., what other layers give to it as parameters are valid.
So, using clean architecture biases us to using instanceof and using it is not bad in scenarios like the one I mentioned. Am I right or am I misunderstanding something?