Laravel 4:如何正确使用存储库中的模型

时间:2013-11-26 15:10:36

标签: php laravel laravel-4

阅读从学徒到工匠和Chris Fidao实施Laravel的书籍,现在我不知道如何正确使用存储库中的模型。

在实施laravel一书中,作者正在以这种方式处理模型:

示例#1

<?php
use MyApp\Interfaces\UserInterface;
use Illuminate\Database\Eloquent\Model;

class UserRepository implements UserInterface
{
    protected $user;

    public function __construct(Model $user)
    {
        $this->user = $user;
    }

    public function find($userId)
    {
        return $this->user->find($userId);
    }
}

但是,这可以通过其他方式完成,而不是将Model作为依赖项注入,如下所示:

示例#2 使用教程http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4-using-repositories/

构建示例
<?php
use MyApp\Interfaces\UserInterface;
use MyApp\Models\User\User;

class UserRepository implements UserInterface
{
    public function find($userId)
    {
        return User::with('profile')->find($userId);
    }
}

为什么在第一个例子中注入模型,为什么不直接使用模型,如例2中所示?

哪种方式正确?为什么?

使用集成到laravel UnitTest包的哪种方式更可测试?

2 个答案:

答案 0 :(得分:2)

示例2很糟糕,因为它将您的存储库与用户模型的特定实现耦合。

每次使用存储库时,都需要实例化Univemba \ Models \ User \ User。 Dependency Injection的整个想法是将任何依赖项注入(发送)到您的对象。如果您的对象需要使用模型,您可以向它发送一个Laravel Eloquent模型,但您的任何同事也可能需要向其发送一个Doctrine模型。但如果你把你的班级与Eloquent结合起来,这是不可能的。

所以在第一个例子中,代码中没有发生实例化,并且它没有像第二个那样直接使用具体类:

return User::with('profile')->find($userId);

它正在实例化过程中接收实现:

public function __construct(Model $user)
{
    $this->user = $user;
}

有更好的方法可以做到这一点,因为它仍然期待一个具体的类,而它应该期待一个接口的实现

public function __construct(ModelInterface $user)
{
    $this->user = $user;
}

在这种情况下,您只需要向您的对象传递一些实现ModelInterface的东西,它可以是

Univemba\Models\EloquentModel

Univemba\Models\DoctrineModel

因为两者都将实施

Univemba\Models\ModelInterface

答案 1 :(得分:0)

我认为如果Repository旨在成为Eloquent的{​​{1}}实现,那么直接使用RepositoryInterface并不是一个坏主意。