Я пытаюсь найти хороший и элегантный способ запроса содержимого базы данных, основанный на «спецификациях» DDD.
В проектировании, управляемом доменом, используется спецификация, чтобы проверить, соответствует ли какой-либо объект, также известный как кандидат, (специфичному для домена) требованию. Например, спецификация IsTaskDone выглядит следующим образом:
class IsTaskDone extends Specification<Task> {
boolean isSatisfiedBy(Task candidate) {
return candidate.isDone();
}
}
Приведенная выше спецификация может использоваться для многих целей, например, его можно использовать для проверки того, была ли задача выполнена, или для фильтрации всех выполненных задач из коллекции. Однако я хочу повторно использовать эту замечательную спецификацию, связанную с доменом, для запроса к базе данных.
Конечно, самым простым решением было бы извлечь все объекты нашего желаемого типа из базы данных и отфильтровать этот список в памяти путем зацикливания и удаления несовпадающих объектов. Но ясно, что это не было бы оптимальным для производительности, особенно когда число сущностей в нашей базе данных увеличивается.
Предложение
Итак, моя идея заключается в создании 'ConversionManager', который переводит мою спецификацию в критерии, специфичные для методов персистентности, например класс предикатов JPA. Услуги выглядят следующим образом:
public interface JpaSpecificationConversionManager {
<T> Predicate getPredicateFor(Specification<T> specification, Root<T> root, CriteriaQuery<?> cq, CriteriaBuilder cb);
JpaSpecificationConversionManager registerConverter(JpaSpecificationConverter<?, ?> converter);
}
Используя наш менеджер, пользователи могут зарегистрировать свою собственную логику преобразования, изолируя спецификацию домена от логики, специфичной для персистентности. Чтобы свести к минимуму конфигурацию нашего менеджера, я хочу использовать аннотации для моих классов конвертеров, позволяя менеджеру автоматически регистрировать эти конвертеры.
Реализации репозитория JPA могут затем использовать мой менеджер с помощью внедрения зависимостей, чтобы предложить метод поиска по спецификации. Предоставление поиска по спецификации должно значительно сократить количество методов в нашем интерфейсе репозитория.
В теории все это звучит прилично, но я чувствую, что упускаю что-то критическое. Что вы, ребята, думаете о моем предложении, соответствует ли оно образу мышления DDD? Или уже есть фреймворк, который делает что-то идентичное тому, что я только что описал?