Этот вопрос проверяет понимание паттерна Repository и его применения в Laravel для абстракции доступа к данным и улучшения тестируемости кода.
Репозиторий в Laravel используется для абстракции доступа к данным, инкапсулируя логику запросов к базе данных. Он полезен когда нужно отделить бизнес-логику от способа хранения данных или когда сложные запросы повторяются в разных местах приложения. Репозиторий упрощает тестирование, позволяя подменять реальную базу данных моками.
Паттерн Repository предоставляет уровень абстракции между бизнес-логикой и слоем данных, инкапсулируя всю логику работы с хранилищем данных.
Скрывает детали реализации хранения данных
Позволяет легко менять источник данных (БД, API, файлы)
Повторное использование сложных запросов
Единое место для модификации запросов
class UserRepository {
public function findActiveUsers(): Collection {
return User::where('active', true)
->with('profile')
->orderBy('created_at', 'desc')
->get();
}
public function findUsersWithRecentActivity(int $days = 7): Collection {
return User::whereHas('activities', function ($query) use ($days) {
$query->where('created_at', '>=', now()->subDays($days));
})->get();
}
}Легко мокать репозитории в тестах
Изоляция бизнес-логики от базы данных
// Тестирование сервиса с моком репозитория
public function test_user_creation() {
$userRepository = Mockery::mock(UserRepository::class);
$userRepository->shouldReceive('create')
->once()
->andReturn(new User());
$service = new UserService($userRepository);
$result = $service->createUser(['name' => 'John']);
$this->assertInstanceOf(User::class, $result);
}Когда запросы к базе данных сложные и повторяются
При необходимости легко менять реализацию хранения
Когда важна простота unit-тестирования
Для изоляции тестов от базы данных
Когда данные приходят из разных источников
При интеграции с внешними API
interface UserRepositoryInterface {
public function find(int $id): ?User;
public function create(array $data): User;
public function update(User $user, array $data): bool;
public function delete(User $user): bool;
public function findByEmail(string $email): ?User;
}
class EloquentUserRepository implements UserRepositoryInterface {
public function find(int $id): ?User {
return User::find($id);
}
public function create(array $data): User {
return User::create($data);
}
// ... остальные методы
}
// Регистрация в Service Provider
$this->app->bind(UserRepositoryInterface::class, EloquentUserRepository::class);Когда запросы простые и не повторяются
Для маленьких проектов с минимальной бизнес-логикой
Когда overhead от создания репозиториев не оправдан
Репозитории стоит использовать в сложных приложениях с насыщенной бизнес-логикой, где важны тестируемость и возможность легкой смены реализации доступа к данным.