阅读从学徒到工匠和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包的哪种方式更可测试?
答案 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
并不是一个坏主意。