DDD: договор репозитория - PullRequest
       35

DDD: договор репозитория

4 голосов
/ 05 сентября 2011

В разных местах я читал, что одним из важных требований в 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.

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

Ответы [ 3 ]

2 голосов
/ 05 сентября 2011

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

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

blogs.FindByFilter(filter);

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

blogs.RequireModeratorAttention();
1 голос
/ 05 сентября 2011

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

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

Если у вас есть команда, которая изменяет адрес пользователя, лучше иметь репозиторий сМетод FindUserById, чем иметь некоторый волшебный код Hibernate на уровне приложения.Для этого есть две причины

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

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

1 голос
/ 05 сентября 2011

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

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

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

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

...