Laravel - 使用存储库模式

时间:2014-02-16 01:06:21

标签: php service dependency-injection laravel repository-pattern

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

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

app/
  Acme/
    Repositories/
      RepositoryServiceProvider.php
      Product/
        EloquentProduct.php
        ProductInterface.php
      Category/
        EloquentCategory.php
        CategoryInterface.php

示例ProductInterface.php

<?php namespace GD\Repositories\Product;

interface ProductInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

示例CategoryInterface.php

<?php namespace GD\Repositories\Category;

interface CategoryInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

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

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

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

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

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

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

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

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

public function with($relation)
{
  return Category::with($relation);
}

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

2 个答案:

答案 0 :(得分:18)

您过度思考,存储库只是您controllermodel之间的链接/桥梁,因此控制器直接使用repository类而不是model您可以使用model从那里声明您的方法,例如:

<?php namespace GD\Repositories\Category;

interface CategoryInterFace{

    public function all();

    public function getCategoriesWith($with);

    public function find($id);
}

现在在存储库类中实现接口:

<?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):
    }
}

在控制器中使用它:

<?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'));
    }

}

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

更新:我在这里写了一篇文章:LARAVEL – USING REPOSITORY PATTERN

答案 1 :(得分:1)

有一种非常简单的方法可以做到这一点,并在此链接中深入探讨

http://heera.it/laravel-repository-pattern#.U6XhR1cn-f4

我一直在寻找确切的解决方案,到目前为止它运作良好

所以你的想法就是在你的存储库代码中声明这个

public function __construct(\Category $category)
{
    $this->category = $category;
} 
public function getAllUsers()
{
    return $this->category->all();
}

public function __call($method, $args)
{
    return call_user_func_array([$this->category, $method], $args);
}

在某些函数缺失时强制调用Model