Repository - патерн, що ховає доступ до даних за інтерфейсом: код працює з PostRepositoryInterface, не знаючи, звідки беруться записи.
interface PostRepositoryInterface
{
public function published(): Collection;
}
class EloquentPostRepository implements PostRepositoryInterface
{
public function published(): Collection
{
return Post::where('is_published', true)->get();
}
}
Питання зі співбесіди зазвичай про те, чи це потрібно тут. Аргумент «щоб замінити ORM» на практиці не спрацьовує: Eloquent - це Active Record, його моделі пронизують увесь застосунок, і підміна сховища все одно означала б переписування. Заміни ORM у живому проєкті майже не трапляється.
Аргумент «щоб тестувати» теж слабкий у Laravel: є RefreshDatabase і фабрики, тож тест із реальною базою пишеться просто й перевіряє більше, ніж мок репозиторію.
Що при цьому втрачається: зникають скопи, ліниві зв'язки й with() у місці виклику - або репозиторій обростає методами на кожну комбінацію фільтрів, або починає повертати Builder, і абстракція протікає.
Коли Repository справді доречний:
- Дані живуть не в Eloquent - зовнішнє API, Elasticsearch, кілька джерел за одним інтерфейсом.
- Домен свідомо відокремлений від фреймворку (DDD), і моделі домену не є Eloquent-моделями.
Що зазвичай працює краще: локальні скопи для повторюваних вибірок і Action/Service-класи для операцій. Вони дають ту саму зібраність без прошарку, який дублює Eloquent.