1

我最近观看了这个视频,想更改我的Laravel控制器,以便使用 Laravel 的 IoC 容器管理它们的依赖项。该视频讨论了为模型创建接口,然后为使用的特定数据源实现该接口。

我的问题是:当使用扩展 Eloquent 的类实现接口并将该类绑定到控制器以便可以从 访问时$this->model,我是否还应该为 Eloquent 模型创建接口和实现,这些模型在调用方法时可能会返回,例如$this->model->find($id)?Model 和 ModelRepository 应该有不同的类吗?

换一种说法:new Model当我的模型在$this->model.

4

2 回答 2

9

通常,是的,执行该模式(存储库模式)的人有一个接口,其中定义了一些您的应用程序将使用的方法:

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()

于 2013-09-03T21:35:53.363 回答
0

我用过$newModel = $this->model,它对我有用。

于 2013-09-03T20:22:59.097 回答