Skip to main content
1 of 2
amon
  • 135.9k
  • 27
  • 295
  • 386

If you want to add a method to a class hierarchy without actually adding the method, consider the Visitor Pattern. You could create a validation visitor, and let each entity select the appropriate method of the visitor:

interface EntityVisitor {
  void visitA(AEntity a);
  void visitB(BEntity b);
}

class ParentEntity {
  void accept(EntityVisitor v);
}

class EntityA ... {
  ...
  @Override void accept(EntityVisitor v) {
    v.visitA(this);
  }
}

class Validation implements EntityVisitor {
  ...
}

class EntityRepository ... {
  void save(List<ParentEntity> list) {
    list.ForEach(e -> {
      Validation validation = new Validation(this);
      e.accept(validation);
      ...
    });
  }
}

The validation visitor can have access to both the entity and the repository (in order to make further queries), and will therefore be able to perform the full validation.

However, performing validation based on the result of multiple queries can lead to data integrity problems. The repository should either make sure to use database transactions (and offer an API that clearly communicates when modifications have been committed), or the relevant integrity checks should be done within the database, e.g. using constraints in an SQL database. In some cases, the validation checks can also be expressed as part of an insert or update query.

amon
  • 135.9k
  • 27
  • 295
  • 386