Laravel 存储库模式说明

Laravel repository pattern explanation

我正在 Laravel 5.4 项目中使用 Repository Pattern(我对这种模式很陌生)。我已经在网上对此进行了很多讨论,但我仍然有两个重要问题:

> 问题 #1:

假设我使用 Laravel ORM Eloquent 并且我有一个如下所示的界面:

<?php

namespace App\Repositories\User;

interface UserRepoInterface
{
    /**
     * @param array $user
     */
    public function update(array $request, User $user);
}

大家可以看到我把eloquentUser这个模型指定成了一个参数。

eloquent 实现如下所示:

public function update(array $request, User $user)
{
    $user->name             = $request['name'];
    $user->last_name        = $request['last_name'];
    $user->email            = $request['email'];
    $toUpdate->save();
}

所以我的问题是:

在我的界面中对 eloquent User 模型进行硬编码是错误的吗? 在网络上的许多示例中,我看到人们这样做但是什么如果我想用基于文件的实现交换 eloquent 实现?这是个问题,因为我必须将 User 模型传递给更新方法!

如果我只声明 $user 而不是 User $user,这个问题的解决方案是什么?

> 问题 #2:

我应该如何处理分页?

例如,在我的 eloquent UserRepository 中,我有一个如下所示的方法:

public function index()
{
    return User::orderBy('name', 'asc')
        ->withCount('messages')
        ->with('corporation')
        ->paginate(10);
}

这是错误的吗?我应该只在我的控制器中分页吗?

一个好的解释会对我有很大帮助。

问题 1

Laravel 使用 ActiveRecord 作为其模型 + 数据访问层的模式。

此模式 objective 让事情变得更简单、更快捷。当您使用存储库模式时,您有点 运行 远离它。

要真正使用存储库模式,您必须创建数据传输对象 DAT(在 java 他们称之为 POJO)。然后,将 Eloquent 实体用作实体管理器。

POPO

class User {

  private $id;
  private $a;

  public setId ($id) { $this->id = $id; } 
  public getId () { return $this->id; } 

  public setA ($a) { $this->a = $a; } 
  public getA () { return $this->a; } 
}

实体管理器

class UserEloquent extends Eloquent {
   protected $_table = 'user';
}

存储库

class EloquentUserRepository implements UserReposistory {
   private $em;

   public __constructor (UserEloquent $em) { $this->em = $em; }

   public update (User $dat) {
     $user  = $em->find($dat->getId());
     $user->a = $dat->getA();
     $user->save();
   }
}

你能看出它有多冗长吗?如果你真的想使用这种方法,我建议你使用 Doctrine.

但是如果您想按原样使用 ActiveRecord,我建议您在 rails 项目上查看一些 ruby!他们在这个模式中真的很棒:)

现在我真正的想法是:做对项目有利的事情。让它变得简单,与您的团队一起思考并为您构建最佳实践。不要总是使用相同的模式,因为有人告诉你。

如果项目小而快,就使用框架给你的东西(我不是说放松并编写糟糕的代码)。如果这是一个大项目,团队中有很多开发人员,并且您知道最终可能想要更改数据访问层,请考虑存储库模式。

当然有时我们会做出错误的架构决定,但这就是我们学习的方式!并继续阅读有关模式的内容,我认为您正在走一条成为伟大架构师的好道路:)

问题 2

这取决于您在上面做出的决定。如果它 Eloquent 按原样使用 ActiveRecord,那么在哪里调用它并不重要(控制器或某个中间 class)。只要遵循一些模式。如果您在 Controller 中调用 always 在 Controller 中执行。否则你会迷失在代码中。

使用 Repository,我觉得在 repository 里面没问题 :)