Стандартизация Шаблона репозитория методов

Все я пытаюсь узнать корректное определение шаблона репозитория.

Мое исходное понимание было этим (чрезвычайно dumbed вниз)

  • Разделите свои Бизнес-объекты от Ваших Объектов данных
  • Стандартизируйте методы доступа на уровне доступа к данным.

Я действительно видел 2 других реализации, и нет никаких формальных примеров онлайн, те я видел, убраны в книгах.

Реализация 1:

public Interface IRepository{
      List GetAll();
      void Create(T p);
      void Update(T p);
}


public interface IProductRepository: IRepository {
      //Extension methods if needed
       List GetProductsByCustomerID();
}

Реализация 2:

public interface IProductRepository {
      List GetAllProducts();
      void CreateProduct(Product p);
      void UpdateProduct(Product p);
      List GetProductsByCustomerID();
}

Заметьте, что первым является универсальный Get/Update/GetAll, и т.д., вторым является больше того, как что я определил бы "ДАО".

Оба совместно используют извлечение от Ваших объектов данных. Который я люблю, но я могу сделать то же с простым ДАО. Однако вторая часть стандартизирует операции доступа, в которых я вижу значение, если бы Вы реализуете это предприятие, широкие люди легко знали бы набор методов доступа для Вашего репозитория.

Разве я неправ предположить, что стандартизация доступа к данным является интегральной частью этого шаблона? Если бы оба корректны, почему можно было бы принять решение сделать реализацию 2?

У носорога есть хорошая статья о реализации 1, и конечно MS имеет неопределенное определение, и пример реализации 2 здесь.

36
задан Nix 3 May 2010 в 12:13
поделиться

5 ответов

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

Не существует такой вещи, как «реализация канонического репозитория».

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

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

http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx

20
ответ дан 27 November 2019 в 06:14
поделиться

Из «Паттернов архитектуры корпоративных приложений» Мартина Фаулера определение паттерна репозитория следующее:

Посредник между уровнями отображения домена и данных с использованием подобный коллекции интерфейс для доступа к объектам домена.

Итак, оба подхода верны.

8
ответ дан 27 November 2019 в 06:14
поделиться

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

Я рекомендую вашему разработчику IProductRepository получить доступ к общему IRepository через делегирование и ввести его через конструктор, чтобы вы могли составить свой класс, возможно, из многих IRepositories, и сгруппировать их за одним интерфейсом в это имеет смысл.

Я написал блог на эту тему, в то время как он конкретно ссылается на NHibernate, этот шаблон можно применить к любому типу репозитория: Создание общего универсального и расширяемого репозитория NHiberate версии 2

4
ответ дан 27 November 2019 в 06:14
поделиться

С появлением LINQ в .NET стало намного проще реализовать общий шаблон репозитория:

public interface IRepository<T> : IQueryable<T>
{
    void Add(T item);
    void Remove(T item);
}

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

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

2
ответ дан 27 November 2019 в 06:14
поделиться

В дополнение к вашему общему интерфейсу репозитория (реализация 1) и вашему варианту ролевого репозитория (реализация 2) вы также можете рассмотреть общий репозиторий методов:

public interface IRepository
{
    void Save<ENTITY>(ENTITY entity) where ENTITY : DomainEntity;

    ENTITY Load<ENTITY>(Guid id) where ENTITY : DomainEntity;

    IQueryable<ENTITY> Query<ENTITY>() where ENTITY : DomainEntity;

    IQueryable<ENTITY> Query<ENTITY>(IDomainQuery<ENTITY> whereQuery)
        where ENTITY : DomainEntity;
}

Эта третья версия взята из этого поста Джимми Богарда, где он также отдает предпочтение общему интерфейсу репозитория. Я обычно использую базовый класс общего хранилища, который реализует этот интерфейс; таким образом, мне приходится реализовывать только то, что отличается для каждой доменной сущности.

1
ответ дан 27 November 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: