перевод спецификаций в предикаты запросов - PullRequest
4 голосов
/ 28 декабря 2010

Я пытаюсь найти хороший и элегантный способ запроса содержимого базы данных, основанный на «спецификациях» 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? Или уже есть фреймворк, который делает что-то идентичное тому, что я только что описал?

Ответы [ 3 ]

1 голос
/ 28 декабря 2010

Hades - это структура репозитория в качестве оболочки для JPA. Это DDD дружественный. Он поддерживает DDD Технические характеристики из коробки. Я также предлагаю вам взглянуть на эту статью из InfoQ .

0 голосов
/ 10 апреля 2011

Я действительно читал эту статью, но спецификации hades требуют, чтобы вы включили логику JPA в свой Спецификация. Спецификации относятся к конкретной области и должны храниться отдельно от любого типа логика персистенции.

А как насчет аннотаций JPA, человек ...? Как вы думаете, ваши доменные объекты должны быть отделены от аннотаций JPA?

Я думаю, что решение, предоставленное Hades (которое теперь известно как " spring-data-jpa "), является лучшим решением, чем то, которое представлено в книге Эванса: Эрик Эванс показывает пример, где " «Спецификация» вызывает «Репозиторий», который сам называет «Спецификация»! Мне действительно было интересно, как клиентский код будет проходить только через спецификацию, а не использовать репозиторий напрямую. Решение, предоставленное Hades / Spring-data-jpa, мне подходит, можно поместить JPA в доменную логику, потому что JPA предназначен для перехода на уровень домена.

РЕДАКТИРОВАТЬ: я забыл упомянуть, что Эрик Эванс реализует «двойную диспетчеризацию», это не глупая циклическая зависимость между спецификацией и репозиторием, но, как уже упоминалось выше, это не мешает разработчикам обходить реализацию спецификации.

0 голосов
/ 28 декабря 2010

В мире .NET это покрыто LINQ . Я не знаю эквивалента Java.

...