Вопрос

Я читал в разных местах, что одно важным требованием в DDD состоит в том, чтобы иметь ограниченный контракт на хранилище:

findByName(string name)
findByEmail(string email)
etc.

И не предоставлять общий интерфейс запроса:

findBySpecification(Specification spec)

Я понимаю, почему это важно: иметь возможность издеваться над репозиторием для тестов или изменить основную структуру устойчивости.

Хотя это правило не так сложно применять на протяжении всего приложения, я не могу понять, как его применять, когда речь идет о предоставлении пользователю формой «расширенный поиск».

Допустим, у меня есть форма, которая позволяет искать посты в блоге ключевое слово, по свидание, по автор, так далее.

Эти критерии свободно объединяются, я, очевидно, не могу предоставить метод для каждого варианта использования:

findByKeyword(string keyword)
findByDateRange(Date from, Date to)
findByKeywordAndDateRange(string keyword, Date from, Date to)
findByDateRangeAndAuthor(Date from, Date to, User author)
etc.

Я что -то упускаю или это одно из исключений из правила?

Это было полезно?

Решение

Нет ничего плохого в прохождении Технические характеристики как параметр в репозиторий. Это на самом деле очень хороший способ решения метода взрыва на интерфейсе репозитория. Взгляните на это отвечать. Анкет «Фильтр» может быть более подходящее имя, чем «спецификация» для сценария «расширенный поиск». Я думаю, что этот код не будет нарушать никаких руководящих принципов DDD:

Filter filter = new FilterBuilder()
    .WithinDateRange(dateRange)
    .IncludingKeywords("politics", "news")
    .ByAuthor("John Smith")
    .Build();

blogs.FindByFilter(filter);

Обратите внимание, что код, который создает фильтр, может жить за пределами домена. Потому что это не будет нарушать каких -либо правил домена. Что если есть правило как «Блоги, опубликованные анонимным автором, должны быть одобрены модератором»? Хотя это может быть выражено с помощью фильтра, это будет внешним видом бизнес -логики. Будет больше смысла помещать это правило в код домена и иметь специальный метод репозитория, например:

blogs.RequireModeratorAttention();

Другие советы

Паттерн репозитория имеет два основных преимущества:

  1. Он отделяет ваше приложение от вашего упорного уровня и идиомы.
  2. Он централизует и ограничивает доступ к данным к четко определенным и понятным сегментам доменов (методы доступа к данным в хранилище имеют четко определенный результат и являются разумно проверенными).

Если вы используете экземпляр шаблона спецификации, предоставленный вашим уровнем постоянства (например, критерии NHIBERNATE), вы отрицаете выгоду. Использование шаблона спецификации вообще (даже тот, который вы катитесь сами), вниз по преимуществу номер два.

При этом, в некоторых ситуациях, таких как поисковые интерфейсы, необходима спецификация - просто убедитесь, что выкатайте свои собственные.

Хотя это правило не так сложно применять на протяжении всего приложения, я не могу понять, как его применять, когда речь идет о предоставлении пользователю формой «расширенный поиск».

На самом деле, вам не нужно платить стоимость всех этих абстракций, если все, что вам нужно, это форма поиска. Репозиторий (по крайней мере, в контексте DDD) был разработан для абстрагирования нюансов стойкости из бизнес -логики (прикладной слой).

Если у вас есть команда, которая меняет адрес пользователя, лучше иметь репозиторий с помощью метода FinduserByID, чем иметь какой -то волшебный код спящего сочинения на уровне приложения. Есть две причины для этого

  • Вы можете проверить уровень приложения с помощью упорного уровня (репозитории) высмеивает
  • Уровень приложений - это то, что вас волнует, потому что это бизнес -логика

Вам не нужно все это, чтобы просто получить некоторые данные для пользовательского интерфейса. Я бы предложил использовать специализированные классы «искателя», которые могут даже жить в слое пользовательского интерфейса. Они могут работать либо в абстрактной «спецификации», либо (даже лучше) на горе гибернат (или ваш любимый ORM). Я написал сообщение в блоге об этом подходе здесь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top