通常,是的,执行该模式(存储库模式)的人有一个接口,其中定义了一些您的应用程序将使用的方法:
interface SomethingInterface {
public function find($id);
public function all();
public function paged($offset, $limit);
}
然后你创建一个实现。如果您使用的是 Eloquent,那么您可以进行 Eloquent 实现
use Illuminate\Database\Model;
class EloquentSomething {
protected $something;
public function __construct(Model $something)
{
$this->something = $something;
}
public function find($id)
{
return $this->something->find($id);
}
public function all() { ... }
public function paged($offset, $limit) { ... }
}
然后你创建一个服务提供者将它们放在一起,并将其添加到app/config/app.php
.
use Something; // Eloquent Model
use Namespace\Path\To\EloquentSomething;
use Illuminate\Support\ServiceProvider;
class RepoServiceProvider extends ServiceProvider {
public function register()
{
$app = $this->app;
$app->bind('Namespace/Path/To/SomethingInterface', function()
{
return new EloquentSomething( new Something );
});
}
}
最后,您的控制器可以使用该接口作为类型提示:
use Namespace/Path/To/SomethingInterface;
class SomethingController extends BaseController {
protected $something;
public function __construct(SomethingInterface $something)
{
$this->something = $something;
}
public function home() { return $this->something->paged(0, 10); }
}
应该是这样的。对任何错误表示歉意,这未经测试,但我经常这样做。
缺点:
更多代码:D
优点:
- 能够切换实现(而不是 EloquentSomething,可以使用 ArraySomething、MongoSomething 等),而无需更改控制器代码或任何使用接口实现的代码。
- 可测试——你可以模拟你的 Eloquent 类并测试存储库,或者模拟你的构造函数依赖并测试你的控制器
- 可重用 - 您可以
App::make()
在应用程序的任何位置获取具体的 EloquentSomething,并在代码中的任何位置重用 Something 存储库
- 存储库是添加额外逻辑的好地方,比如一层缓存,甚至是验证规则。库存在您的控制器中乱七八糟。
最后:,因为我可能把所有这些都输入了,但仍然没有回答你的问题(wtf?!),你可以使用$this->model
. 这是创建新事物的示例:
// Interface:
public function create(array $data);
// EloquentSomething:
public function create(array $data)
{
$something = this->something->newInstance();
// Continue on with creation logic
}
关键是这个方法,newInstance()。