关于在项目中增加repository的迷惑, 请大家帮帮忙.

本人入行尚浅,在工作中发现controller里面要写的代码量太乱了,又是验证又是逻辑的. 所以在网上查了下,发现可以加个repository层. 查看了下一般的做法,貌似是创建一个interface或者abstract.然后去继承或者实现它们.里面定义find(),first(),where(),get(),delete(),update()等常用的方法. 在这里想像大神们请教下,如果单一的方法解决不了怎么办呢? 就是说查询条件很多,可能同时有where(),whereIn(),或者between,那么这些简单的操作就无法完成了, 如果实现所有的功能,那不就等于是把eloquent重写了一遍么 ? 或者是在repository中的子类专门定义一个方法来完成单独的一个操作 ? 请指点,谢谢.

阅读 2.7k
2 个回答

先解释一下我对repository的理解
repository的用意就是在model和controller中间加一个“中间层”。假如你现在有一个Model叫CDEloquent,用于在关系型数据库中存储唱片信息,它继承了CD Interface
CD Interface

namespace App\Interface
interface CD
{
    public function getName();
    public function getAuthor();
}

CDEloquent

namespace App\Eloquent
use App\Interface\CD
class CDEloquent extends CD
{
    public function getName() 
    {
        //在关系型数据库中的操作
    }
 
    public function getAuthor() 
    {
        //在关系型数据库中的操作
    }
}

然后你就会在Controller中取调用CDEloquent中的方法。
后来因为某些原因你的cd model不使用关系型数据库了而是使用MongoDB。在这时你的Controller里面可能已经调用到CDEloquent中的方法了,有可能你需要修改大量的Controller中的代码。如果当时我们定义一个repository

namespace App\Repository
use App\Eloquent\CDEloquent
class CDRepository
{
    protected $model
    public function setModel(CDEloquent $cd)
    {
        $this->model = $cd;
    }
    public function getName()
    {
        return $this->model->getName();
    } 
    public function getAuthor()
    {
        return $this->model->getAuthor;
    }
}

然后我们在controller中调用CDRepository而不是CDEloquent。等到我们要将model从CDEloquent换到使用mongodb存储时只需要先定义一个CDMongo

namespace
App\Mongo
use App\Interface\CD
class CDMongo extends CD
{
    public function getName()
    {
        \\mongodb中的操作
    }
    public function getAuthor()
    {
        \\mongodb中的操作
    }
}

然后将respository中的setModel改为

public function setModel(CDMongo $cd)
{
        $this->model = $cd;
}

这样我的controller中的代码不需要改任何地方。
因此respository的作用是为controller层提供一个统一的接口,然后具体的实现是由respository中的model来实现的。respository只是一个逻辑抽象层。它将controller和model之间的耦合性降低了。
如果你的业务只是用关系型数据库存放并且不会更改的话,就像你说的,完全没有必要加respository这一层。只有当model的类型有可能改变的时候才会加。

如果使用了respository。你可以把respository看成是以前model层的代理,在controller中使用model的地方改使用respository;

至于你说controller的功能太乱了又是验证又是逻辑的,我的想法是:
以前我们开发讲究MVC。但是现在前后端分离是主流,对于后台开发者就没有view层了,只剩下MV;
在MV之间可以加一个respository,上面已经说了就不再说了。其实我们也可以把传统的controller拆为两个层:controller和logic。controller只负责接受请求,验证数据,发送回复。具体的业务逻辑放到logic中去。这样无论是代码的清晰度还是业务逻辑都会很清晰。
以上是个人的一些观点,如有错误还请见谅

你说的只是基础的
比如:

public function getAgeLargerThan($age)
{
    return $this->user
        ->where('age', '>', $age)
        ->orderBy('age')
        ->get();
}

可以看一下这篇文章:如何使用 Repository 模式?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题