Подтвердить что ты не робот

Плюсы и минусы репозиториев DDD

Плюсы:

  • Хранилища скрывают сложные запросы.
  • Методы репозитория могут использоваться как границы транзакций.
  • ORM можно легко насмехаться

Минусы:

  • Структуры ORM предлагают уже такую ​​коллекцию, как интерфейс к постоянным объектам, каково намерение репозиториев. Таким образом, хранилища добавляют дополнительную сложность в систему.
  • комбинаторный взрыв при использовании методов findBy. Эти методы можно избежать с помощью объектов критериев, запросов или объектов-примеров. Но для этого не требуется никакого репозитория, потому что ORM уже поддерживает эти способы поиска объектов.
  • Так как репозитории представляют собой совокупность совокупных корней (в смысле DDD), нужно создавать и передавать вокруг совокупных корней, даже если изменяется только дочерний объект.

Вопросы:

  • Какие плюсы и минусы вы знаете?
  • Вы рекомендуете использовать репозитории? (Почему или почему нет?)
4b9b3361

Ответ 1

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

Когда вы используете ORM, вы должны использовать свой API как можно более ограниченным образом, предоставляя себе фасад, возможно, это домен. Поэтому, несмотря на то, что ваш домен все равно будет видеть репозиторий. Тот факт, что он имеет ORM с другой стороны, является "детальностью реализации".

Ответ 2

Репозиторий позволяет сфокусировать модель домена, спрятав детали доступа к данным за интерфейсом, основанным на вездесущем языке. При проектировании репозитория вы концентрируетесь на концепциях домена, а не на доступе к данным. С точки зрения DDD использование ORM API напрямую эквивалентно непосредственному использованию SQL.

Вот как выглядит хранилище в приложении обработки заказа:

List<Order> myOrders = Orders.FindPending()

Обратите внимание, что нет таких условий доступа к данным, как "Критерии" или "Запрос". Внутренний метод "FindPending" может быть реализован с использованием Hibernate Criteria или HQL, но это не имеет ничего общего с DDD.

Взрыв метода действителен. Например, вы можете использовать несколько методов, например:

    Orders.FindPending()
    Orders.FindPendingByDate(DateTime from, DateTime to)
    Orders.FindPendingByAmount(Money amount)
    Orders.FindShipped()
    Orders.FindShippedOn(DateTime shippedDate)
    etc

Это можно улучшить, используя шаблон спецификации. Например, вы можете иметь класс

class PendingOrderSpecification{
    PendingOrderSpecification WithAmount(Money amount);
    PendingOrderSpecification WithDate(DateTime from, DateTime to)
    ...
}

Таким образом, хранилище будет выглядеть так:

Orders.FindSatisfying(PendingOrderSpecification pendingSpec)
Orders.FindSatisfying(ShippedOrderSpecification shippedSpec)

Другой вариант - иметь отдельный репозиторий для ожидающих и отправленных заказов.

Ответ 3

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

Я полагаю, что если вы не хотите отделять свой DAL, вам не нужен репозиторий. Но для этого есть много преимуществ, таких как тестируемость.

Что касается комбинаторного взрыва методов "Найти": в .NET вы можете вернуть IQueryable вместо IEnumerable и разрешить вызывающему клиенту выполнять Linq-запрос на нем вместо использования метода Find. Это обеспечивает гибкость для клиента, но приносит жертвы возможность обеспечить четко определенный, проверяемый интерфейс. По сути, вы торгуете одним набором преимуществ для другого.