Java интерфейс для entity/dto или передача метода по ссылке?

Я пытаюсь создать класс валидатор с несколькими простыми правилами проверки. Эти правила могут применяться одинаково к разным типам Hibernate entity (или DTO), и я хотел бы унифицировать этот класс без создания разных реализаций.

Я пытаюсь сделать это с помощью дженериков, но проблема в том, что, хотя каждый тип валидируемого объекта имеет определенный геттер (getCatalog), я не могу вызвать его с помощью дженериков не реализуя общий интерфейс или не расширяя абстрактный класс. Я думаю, что интерфейс для entity / dto в таком случае не является хорошим выбором, хотя может я и не прав и интерфейс типа Cataloged или HasCatalog допустим для таких целей..

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();
}

}


Основная моя цель - избавиться от этого Function<T, Catalog> catalogGetter

Может есть более красивый способ или вариант с интерфейсом тут допустим?
  • Вопрос задан
  • 306 просмотров
Пригласить эксперта
Ответы на вопрос 1
vabka
@vabka
Токсичный шарпист
1. Я бы не стал делать в валидаторе сигнатуру, которая принимает список объектов.
Как минимум из-за того, что ему не нужен весь интерфейс, который даёт List. А как максимум - это просто не красиво.
2. Я бы не стал валидировать объекты, которые лежат в базе (считается, что раз объект попал в базу, то он уже валиден). Так что имеет смысл валидировать только DTO.
3. Вы правы, прокидывать лямбду для геттера в метод - это плохо.
я бы сделал билдер для валидатора, наподобие
// Псевдо-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:
Вдохновлялся шарповым FluentValidation - можете посмотреть на его API, но я бы не стал пытаться его портировать на Java, тк там много зависимостей от чисто шарповых штук
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽
19 апр. 2024, в 23:00
5000 руб./за проект
19 апр. 2024, в 20:43
20000 руб./за проект