Шаблон репозитория против DAL - PullRequest
90 голосов
/ 14 ноября 2008

Это одно и то же? Только что закончили смотреть Учебное пособие Роба Коннери * , и они, похоже, похожи на техникумы. Я имею в виду, что когда я реализую объект DAL, у меня есть методы GetStuff, Add / Delete и т. Д., И я всегда сначала пишу интерфейс, чтобы потом можно было переключать db.

Я что-то путаю?

Ответы [ 11 ]

85 голосов
/ 15 ноября 2008

Ты определенно не тот, кто путает вещи. : -)

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

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

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

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

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

public interface IRepository : IDisposable
{
    T[] GetAll<T>();
    T[] GetAll<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
    void Delete<T>(T entity);
    void Add<T>(T entity);
    int SaveChanges();
    DbTransaction BeginTransaction();
}

Это DAL или хранилище? В этом случае я думаю, что оба.

Kim

41 голосов
/ 15 ноября 2008

Репозиторий - это шаблон, который можно применять различными способами, в то время как уровень доступа к данным несет очень четкую ответственность: DAL должен знать, как подключиться к вашему хранилищу данных для выполнения операций CRUD.

Репозиторий может быть DAL, но он также может находиться перед DAL и выступать в качестве моста между уровнем бизнес-объекта и уровнем данных. Какая реализация будет использоваться, будет варьироваться от проекта к проекту.

23 голосов
/ 05 марта 2009

Одно большое отличие состоит в том, что DAO - это общий способ справиться с постоянством для любого объекта в вашем домене. С другой стороны, хранилище имеет дело только с совокупными корнями.

12 голосов
/ 23 июня 2009

Я искал ответ на аналогичный вопрос и согласен с двумя наиболее высоко оцененными ответами. Пытаясь уточнить это для себя, я обнаружил, что , если Спецификации, которые идут рука об руку с шаблоном Repository, реализованы как первоклассные члены модели предметной области, то я могу

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

Я могу даже пойти так далеко и заявить, что , если не используется шаблон Repository вместе с шаблоном Specification, на самом деле это не "Repository", а DAL. Придуманный пример в псевдокоде:

specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)

assert that specification200.isSpecialCaseOf(specification100)

specificationAge = new AccountIsOlderThan('2000-01-01')

combinedSpec = new CompositeSpecification(
    SpecificationOperator.And, specification200, specificationAge)

for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

Подробнее см. Эссе Фаулера о спецификациях (это то, на чем я основывался выше).

DAL будет иметь специальные методы, такие как

IoCManager.InstanceFor<IAccountDAO>()
    .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')

Вы можете видеть, как это может быстро стать громоздким, особенно если учесть, что при этом подходе необходимо определить каждый из интерфейсов DAL / DAO и реализовать метод запроса DAL.

В .NET запросы LINQ могут быть одним из способов реализации спецификаций, но объединение спецификаций (выражений) может быть не таким гладким, как в собственном решении. Некоторые идеи для этого описаны в этом SO Вопросе .

2 голосов
/ 05 марта 2009

Мое личное мнение таково, что все дело в отображении, см .: http://www.martinfowler.com/eaaCatalog/repository.html. Таким образом, вывод / ввод из репозитория являются объектами домена, которые в DAL могут быть чем угодно. Для меня это важное добавление / ограничение, так как вы можете добавить реализацию репозитория для базы данных / службы / чего угодно с другим макетом, и у вас есть четкое место, чтобы сконцентрироваться на выполнении сопоставления. Если бы вы не использовали это ограничение и не использовали отображение в другом месте, то использование разных способов представления данных может повлиять на код в тех местах, которые не должны изменяться.

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

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

1 голос
/ 15 ноября 2008

Все дело в интерпретации и контексте. Они могут быть очень похожими или даже очень разными, но пока решение работает, что в названии!

0 голосов
/ 06 мая 2010

Репозиторий является шаблоном, это способ реализовать вещи стандартизированным способом повторного использования кода, как мы можем.

0 голосов
/ 29 декабря 2009

Во внешнем мире (например, код клиента) хранилище такое же, как и в DAL, за исключением:

(1) его методы вставки / обновления / удаления ограничены, чтобы иметь объект контейнера данных в качестве параметра.

(2) для операции чтения может потребоваться простая спецификация, например DAL (например, GetByPK) или расширенная спецификация.

Внутренне он работает с Data Mapper Layer (например, контекстом структуры объекта и т. Д.) Для выполнения фактической операции CRUD.

Что не означает шаблон репозитория: -

Кроме того, я часто сталкиваюсь с тем, что в качестве примера реализации шаблона репозитория часто путают отдельный метод Save, кроме методов Insert / Update / Delete, которые фиксируют все изменения в памяти, выполняемые методами insert / update / delete, в база данных. У нас может быть определенно метод Save в репозитории, но он не несет ответственности за репозиторий за изоляцию в памяти CUD (Create, Update, Delete) и методов персистентности (которые выполняют фактическую операцию записи / изменения в базе данных), но Ответственность за единицу работы.

Надеюсь, это поможет!

0 голосов
/ 15 ноября 2008

Итак, в большинстве (простых) случаев DAO является реализацией репозитория?

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

Я на правильном пути?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...