Laravel - 使用存储库模式

Gra*_*avy 11 php service dependency-injection repository-pattern laravel

我正在尝试学习存储库模式,并且似乎让我自己有点混淆我如何在急切加载关系时使用此存储库模式并将db逻辑保留在我的控制器之外.

快速浏览我的存储库/应用程序结构.

app/
  Acme/
    Repositories/
      RepositoryServiceProvider.php
      Product/
        EloquentProduct.php
        ProductInterface.php
      Category/
        EloquentCategory.php
        CategoryInterface.php
Run Code Online (Sandbox Code Playgroud)

示例ProductInterface.php

<?php namespace GD\Repositories\Product;

interface ProductInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}
Run Code Online (Sandbox Code Playgroud)

示例CategoryInterface.php

<?php namespace GD\Repositories\Category;

interface CategoryInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}
Run Code Online (Sandbox Code Playgroud)

好的,所以简单的部分是使用DI将模型依赖注入控制器.

列出所有带有相关产品的类别更加困难,因为我不再使用雄辩的模型.我正在使用一个没有暴露所有雄辩方法的接口.

如果没有在我的EloquentCategory类中实现with方法,这将无法工作...

public function show($slug)
{
  return Response::json($this->category->findBySlug($slug)->with('products'), 200);
}
Run Code Online (Sandbox Code Playgroud)

我应该创建一个单独的服务类来将两个存储库粘合在一起吗?例如,允许以下内容

public function __construct(ShopService $shop)
{
  $this->shop = $shop;
}

public function show($slug)
{
  return Response::json( $this->shop->getProductsInCategory($slug), 200 );
}
Run Code Online (Sandbox Code Playgroud)

或者,我应该在我的Category Repository中实现with方法吗?

public function with($relation)
{
  return Category::with($relation);
}
Run Code Online (Sandbox Code Playgroud)

最后,我是否了解存储库模式的使用是否正确?

The*_*pha 19

您在想,存储库只是您controller和之间的链接/桥梁model,因此控制器使用repository类而不是model直接在该存储库中,您可以使用modelfrom 来声明您的方法,例如:

<?php namespace GD\Repositories\Category;

interface CategoryInterFace{

    public function all();

    public function getCategoriesWith($with);

    public function find($id);
}
Run Code Online (Sandbox Code Playgroud)

现在在repository类中实现接口:

<?php namespace GD\Repositories\Category;

use \EloquentCategory as Cat; // the model
class CategoryRepository implements CategoryInterFace {
    public function all()
    {
        return Cat::all();
    }

    public function getCategoriesWith($with)
    {
        return Cat::with($with)->get();
    }

    public function find($id)
    {
        return Cat::find($id):
    }
}
Run Code Online (Sandbox Code Playgroud)

要在您的控制器中使用它:

<?php

use GD\Repositories\Category\CategoryInterFace;

class CategoryController extends BaseController {

    public function __construct(CategoryInterFace $category)
    {
        $this->cat = $category;
    }

    public function getCatWith()
    {
        $catsProd = $this->cat->getCategoriesWith('products');
        return $catsProd;
    }

    // use any method from your category
    public function getAll()
    {
        $categories = $this->cat->all();

        return View::make('category.index', compact('categories'));
    }

}
Run Code Online (Sandbox Code Playgroud)

注意:省略了IoC存储库的绑定,因为这不是您的问题而且您知道.

更新:我在这里写了一篇文章:LARAVEL - 使用存储模式.