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 里面没问题 :)
我正在 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 里面没问题 :)