O
O
Oleg Lysenko2020-03-21 23:42:26
Java
Oleg Lysenko, 2020-03-21 23:42:26

Java interface for entity/dto or method passing by reference?

I'm trying to create a validator class with a few simple validation rules. These rules can apply equally to different types of Hibernate entity (or DTO) and I would like to unify this class without creating different implementations.

I'm trying to do this with generics, but the problem is that although each type of object being validated has a specific getter (getCatalog), I can't call it with generics without implementing a common interface or extending an abstract class. I think that an interface for an entity / dto in this case is not a good choice, although I may be wrong and an interface like Cataloged or HasCatalog is acceptable for such purposes..

Validator class

public class Validator<T> {

public boolean validate(List<T> objects, Function<T, Catalog> catalogGetter) {

    if (CollectionUtils.isEmpty(objects)) {
        return false;
    }
    if (differentCatalogsInLoadExist(objects, catalogGetter)) {
        return false;
    }
    if (catalogForObjectNotExists(objects, catalogGetter)) {
        return false;
    }
    return true;
}

private boolean differentCatalogsInLoadExist(List<T> objects, Function<T, Catalog> catalogGetter) {
    return objects.stream()
            .map(catalogGetter)
            .map(catalog -> catalog.getCatalogCode())
            .distinct()
            .count() > 1;
}

private boolean catalogForObjectNotExists(List<T> objects, Function<T, Catalog> catalogGetter) {
    return objects.stream()
            .map(catalogGetter)
            .findFirst()
            .isEmpty();
}

}


My main goal is to get rid of this. Function<T, Catalog> catalogGetter

Maybe there is a more beautiful way or a variant with an interface is acceptable here?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vasily Bannikov, 2020-03-22
@vabka

1. I would not make a signature in the validator that accepts a list of objects.
At least due to the fact that it does not need the entire interface that List provides. And at the very least, it's just not pretty.
2. I would not validate objects that are in the database (it is believed that once an object has entered the database, it is already valid). So it only makes sense to validate DTOs.
3. You are right, throwing a lambda for a getter into a method is bad.
I would make a builder for the validator, like

// Псевдо-Java
var validator = new ValidatorBuilder<MyDto>()
                                .rule(d -> d.catalogues, catalogues -> catalogues.stream().map(c -> c.code).distinct().count() > 1)
                                // etc
                                .build();
var dto = //как-то получаем экземпляр dto
var dtoValid = validator.validate(dto);

PS:
Inspired by Sharp FluentValidation - you can look at its API, but I wouldn't try to port it to Java, as there are a lot of dependencies on pure Sharp stuff

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question