junior
Что такое паттерн Repository?
Repository (Репозиторий) – паттерн, предоставляющий абстракцию для доступа к данным. Репозиторий создаёт иллюзию работы с коллекцией объектов в памяти, скрывая детали хранения (SQL-запросы, ORM, внешние API). Как библиотекарь: вы просите книгу по названию, а он знает, на какой полке и в каком зале она стоит.
Пример
Бизнес-логика ──────▶ Repository (интерфейс)
▲
│ реализует
│
┌──────────┴──────────┐
│ JPA Repository │
│ (инфраструктура) │
└──────────┬──────────┘
│
┌────┴────┐
│ БД │
└─────────┘
Зачем нужен
- Изолирует бизнес-логику от способа хранения данных.
- Упрощает тестирование – можно подставить in-memory реализацию.
- Центральное место для запросов к определённой сущности.
- Соответствует принципу DIP из SOLID.
Пример
Пример кода
// Интерфейс в доменном слое
public interface PaymentRepository {
Payment findById(PaymentId id);
List<Payment> findByStatus(PaymentStatus status);
void save(Payment payment);
void delete(PaymentId id);
}
// Реализация в инфраструктурном слое
@Repository
public class JpaPaymentRepository implements PaymentRepository {
private final PaymentJpaRepo jpaRepo;
private final PaymentMapper mapper;
@Override
public Payment findById(PaymentId id) {
PaymentEntity entity = jpaRepo.findById(id.getValue())
.orElseThrow(() -> new PaymentNotFoundException(id));
return mapper.toDomain(entity);
}
@Override
public void save(Payment payment) {
PaymentEntity entity = mapper.toEntity(payment);
jpaRepo.save(entity);
}
// ...
}
// Spring Data JPA -- упрощённая реализация
public interface PaymentJpaRepo extends JpaRepository<PaymentEntity, Long> {
List<PaymentEntity> findByStatus(String status);
}
Repository vs DAO
| Аспект | DAO (Data Access Object) | Repository |
|---|---|---|
| Ориентация | На таблицу БД | На доменный объект (агрегат) |
| Работает с | Записями | Бизнес-сущностями |
| Гранулярность | Один DAO на одну таблицу | Может использовать несколько таблиц для сборки агрегата |
| Контекст | Инфраструктурный паттерн | DDD-паттерн |
В DDD репозиторий создаётся для каждого Aggregate Root, а не для каждой таблицы. Например, OrderRepository загружает Order вместе с его OrderItem-ами как единый агрегат.
На собеседовании: Интервьюер хочет услышать разницу между Repository и DAO, а также понимание связи с DDD (Aggregate Root). Частая ошибка – считать Repository просто обёрткой над DAO или Spring Data JPA-интерфейсом.