laravel 存储库 - 为什么需要调用接口而不是直接调用存储库文件?

laravel repository - why need to call to interface instead of calling directly to repository file?

我已阅读有关存储库 pattern.So 的信息,我创建了 UserRepositoryInterface.php 文件

namespace App\Interfaces;

use Prettus\Repository\Contracts\RepositoryInterface;

interface UserInterface extends RepositoryInterface
{
    // Code
}

然后我创建了UserRepository.php:

<?php

namespace App\Repositories;

use Prettus\Repository\Eloquent\BaseRepository;
use App\Interfaces\UserInterface;

class UserRepository extends BaseRepository implements UserInterface
{
    public function model()
    {
        return User::class;
    }
}

最后,我在RepositoryServiceProvider.php

中将接口绑定到class
    public function boot()
    {
        $this->app->bind(UserInteface::class, UserRepository::class);
    }

当向 class 注入存储库时,我想知道我应该注入 UserRepository 还是 UserInterface。我读到 UserInterface 应该被注入,但我不明白为什么我们不只使用 UserRepository,它可以更快,不是吗? 有人帮忙吗?

谢谢。

注入接口而不是具体 class 的全部意义在于让 change/extend/maintenance/test.

更容易

现在,在您的例子中,您已经在某些控制器方法或构造函数中注入了 UserRepositoryInterface,比方说。但是 UserRepository class 仍然与 Eloquent 的代码紧密耦合(因为它扩展了 Eloquent 的 class)。

现在假设您正在从另一个 provider/source 获取用户(可能是通过 API 调用从第 3 方获取用户)。您可以在单独的 class \App\Repositories\ApiCallUserRepository 中设置该代码(例如)。

您还可以设置 ApiCallUserRepository(新创建的 class)来实现 \App\Interfaces\UserInterface

当你拥有所有这些时,你唯一应该做的改变就是改变供应商 或者换句话说,您只需要指示应用程序在依赖注入接口时使用哪个具体 class 。此外,这意味着应该从具体的 classes(存储库提供者)到使用存储库(即控制器的方法)的 class 提供相同的数据结构,或者至少接收数据 class/code应该期望提供结构,无论它是 Eloquent 集合还是其他类型的集合。

这样你就可以很好地设置服务,例如获取用户。而且您可以轻松地选择您希望从哪个提供商那里获得用户。

这还不是全部:在执行时(即发出请求时),您可以设置适当的具体 class 或根据任意规则制作额外的代码。在 Laravel 的服务容器中检查 when()->needs()->give() 但我也强烈建议您再次查看完整(页面)docs.

也不要限制自己,而是阅读其他关于 DI 的通用和特定文章:

php-di

designpatternsphp

Symfony DependencyInjection Component

laminas-di

也许所有这些看起来都是开销,但实际上它是以良好、标准、可维护和可测试的方式扩展应用程序的良好起点。

老实说,使用 Eloquent 的存储库只是在浪费时间。 ActiveRecord 所有用于存储和接收数据的逻辑都已在模型中实现。您只是不需要另一个 class 和接口来调用 User::all()。这只是过度工程的一个很好的例子。