Laravel - 使用存储库模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21805939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:02:42  来源:igfitidea点击:

Laravel - Using the Repository Pattern

phpservicedependency-injectionlaravelrepository-pattern

提问by Gravy

I am trying to learn the repository pattern, and seem to have got myself a tad confused with how I can use this repository pattern when eager loading relationships and keep db logic out of my controller.

我正在尝试学习存储库模式,似乎让自己对如何在急切加载关系并将数据库逻辑保持在我的控制器之外时如何使用此存储库模式感到困惑。

A quick overview of my repository / application structure.

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

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

Example ProductInterface.php

示例 ProductInterface.php

<?php namespace GD\Repositories\Product;

interface ProductInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

Example CategoryInterface.php

示例 CategoryInterface.php

<?php namespace GD\Repositories\Category;

interface CategoryInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

Ok, so the easy part is using DI to inject model dependencies into the controller.

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

listing all categories withassociated products is more difficult as I am no longer working with an eloquent model. I am working with an interface which has not exposed all the eloquent methods.

由于我不再使用雄辩的模型,因此列出所有类别以及相关产品更加困难。我正在使用一个没有公开所有雄辩方法的接口。

This won't work without me implementing a withmethod within my EloquentCategory class...

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

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

Should I create a separate service class to glue the two repositories together? e.g. allowing the following

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

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

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

Or alternatively, should I be implementing the with method in my Category Repository?

或者,我应该在我的类别存储库中实现 with 方法吗?

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

Finally, is my understanding of the usage of the Repository Pattern Correct?

最后,我对 Repository Pattern 的用法的理解正确吗?

回答by The Alpha

You are over thinking, repository is just a link/bridge between your controllerand modeland hence controller uses repositoryclass instead of the modeldirectly and in that repository you may declare your methods using the modelfrom there, for example:

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

<?php namespace GD\Repositories\Category;

interface CategoryInterFace{

    public function all();

    public function getCategoriesWith($with);

    public function find($id);
}

Now implement the interface in the repository class:

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

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

To use it in your controller:

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

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

}

Note:Omitted the IoCbinding of the repository because this is not your problem and you know that.

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

Update:I've written an article here: LARAVEL – USING REPOSITORY PATTERN.

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

回答by Germain

There is a really easy way to do this and it is explored in depth in this link

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

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

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

I was looking for the exact solution and it is working well so far

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

so the idea for you would be to declare this in your repository code

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

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

forcing the Model to be called when some functions are missing

当某些功能缺失时强制调用模型