Зачем Repository Interface В паттерн на Laravel

Доброго времени суток друзя.

Хотел бы узнать конкретную причину использования интерфейсов в паттерне Repository.

Вот простой паттерн для наглядности.

RepositoryInterface

<?php

declare(strict_types=1);

namespace App\Repository;

interface UserRepositoryInterface extends BaseRepositoryInterface
{
    public function getByEmail(string $email);
}

Repository для самого интерфейса.

<?php

declare(strict_types=1);

namespace App\Repository\Eloquent;

use App\Models\User;
use App\Repository\UserRepositoryInterface;

final class UserRepository implements UserRepositoryInterface
{
    public function __construct( User $model )
    {}

    public function getByEmail(string $email): User | bool
    {
        $user = $this->model->where('email', $email);

        if($user->exists())
            return $user->first();

        return false;
    }
}

А теперь биндим

$this->app->bind(UserRepositoryInterface::class, UserRepository::class);

Ну и напоследок уже делаем инекцию в классе где нам нужно будет. И оно выглядит так.

final class UserController extends BaseController
{
    public function __construct(
        private readonly UserRepositoryInterface $userRepository
    ){}

    public function profile(UsersGetRequest $request)
    {
        return $this->userRepository->getByEmail(auth()->user()->email);
    }
}

Наконец то дошли до самой сути вопроса. Мы для каждого репозитория создаем для него интерфейс.

Какое реальное приемущество оно нам дает?

Веть мы например в нашем примере можем делать инекцию самого репозитория. Примерно так.

public function __construct(
    private readonly UserRepository $userRepository
){}

И дальше аналогично работать с ним.

Что тогда будет не так? Или где мы можетм столкнутя с проблемой?

Дайте свое мнение?

Спасибо.


Ответы (1 шт):

Автор решения: Алексей Шиманский

Всё до банального просто: soliD.

Представим, что в проекте несколько вариаций репозиторев: один достаёт данные из БД, другой - из памяти, третий - из файла, четвёртый - через API, пятый - из космоса.

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

→ Ссылка