Паттерны доступа к данным: Repository, Unit of Work, Specification

↑ 8.1 Принципы и паттерны проектирования в C♯ · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: senior

Зачем это на собесе

Часть вопроса «нужен ли Repository поверх EF» (см. Repository и Unit of Work поверх EF: нужно ли); здесь сами паттерны.

Объяснение

ПаттернСуть
Repositoryколлекция-подобный интерфейс к агрегатам; скрывает хранилище
Unit of Workотслеживает изменения и сохраняет их одной транзакцией
Specificationобъект-условие запроса, комбинируется (And, Or)
Query Object / Read modelотдельные запросы для чтения (CQRS)
Data Mapper vs Active Recordотделять ли сущность от хранения
Identity Mapодин объект на ключ в рамках сессии
public abstract class Specification<T>
{
    public abstract Expression<Func<T, bool>> Criteria { get; }
    public Specification<T> And(Specification<T> other) => new AndSpec<T>(this, other);
}
public class PaidOrders : Specification<Order> { public override Expression<Func<Order, bool>> Criteria => o => o.Status == Status.Paid; }
public class OrdersOfCustomer(Guid id) : Specification<Order> { public override Expression<Func<Order, bool>> Criteria => o => o.CustomerId == id; }
 
public Task<List<Order>> ListAsync(Specification<Order> spec, CancellationToken ct) => db.Orders.Where(spec.Criteria).ToListAsync(ct);

Repository агрегата: GetAsync(id), Add(order); Unit of Work — SaveChangesAsync в конце use case. В DDD репозитории — на агрегат, а не на таблицу.

Нюансы и подводные камни

  • Generic-репозиторий с IQueryable протекает: детали запросов уходят в вызывающий код.
  • Specification на Expression должна транслироваться в SQL, иначе клиентское вычисление.
  • Репозиторий для чтения (списки, отчёты) лучше заменить запросами напрямую к БД.
  • Транзакционные границы — на уровне use case.

Практика

  1. Реализуйте Specification для фильтров заказов и скомбинируйте их.
  2. Сравните объём кода: DbContext напрямую и репозиторий.
  3. Сделайте отдельный read-запрос для списка вместо репозитория.

Вопросы с ответами

Связанные темы