在 Laravel 应用中使用 Repository Design pattern 模式
🌟 入门
在本教程中,我们将向上一教程中构建的应用程序添加功能。克隆github存储库,运行composer install,npm install并连接到您的数据库。
$ mysql -uroot -p
mysql> create database laravelTaskApp;
如果您在这里有遇到问题,请查看我写过的其他文章 安装MySQL 和 initial Laravel setup. 访问 localhost:8000, 您可以看到一个异步添加和删除任务的应用程序。这意味着它将执行操作并显示最新数据,而无需刷新网页。
这是我们在上一教程中构建的任务应用程序。
🏁 仓库设计模式
在上一教程中,我们在控制器中编写了所有应用程序逻辑。另一种开发方法是将一些调用抽象到称为存储库的PHP类中。这个想法是我们可以将模型与控制器解耦,并为复杂的查询分配可读的名称。
我们将重构我们的应用程序以使用存储库模式。第一步是为app/Repositories/Repository.php.创建文件
<?php
namespace App\Repositories;
use Illuminate\Database\Eloquent\Model;
class Repository implements RepositoryInterface
{
// 类实例上的模型属性
protected $model;
// 将模型绑定到仓库的构造器
public function __construct(Model $model)
{
$this->model = $model;
}
// 获取模型的所有实例
public function all()
{
return $this->model->all();
}
// 在数据库中创建新记录
public function create(array $data)
{
return $this->model->create($data);
}
// 更新数据库中的记录
public function update(array $data, $id)
{
$record = $this->find($id);
return $record->update($data);
}
// 从数据库中删除记录
public functi delete($id)
{
return $this->model->destroy($id);
}
// 显示具有给定id的记录
public function show($id)
{
return $this->model-findOrFail($id);
}
// 获取关联的模型
public function getModel()
{
return $this->model;
}
// 设置关联的模型
public function setModel($model)
{
$this->model = $model;
return $this;
}
// 渴望负载数据库关系
public function with($relations)
{
return $this->model->with($relations);
}
}
该文件定义了我们的Repository类。此类的实例具有一个模型属性,我们将其绑定到一个Eloquent模型。一旦将其绑定到构造函数中,我们就可以从类方法中调用对应的方法,比如:findOrFail
,update
或者 all
。
implements RepositoryInterface部分不是严格必需的,但它为我们的代码增加了一层额外的结构。接口是定义类必须定义的方法的协定。在我们的例子中,界面如下所示:
<?php namespace App\Repositories;
interface RepositoryInterface
{
public function all();
public function create(**array** $data);
public function update(**array** $data, $id);
public function delete($id);
public function show($id);
}
如果我们创建实现该接口的新仓库,我们将始终知道这些方法已经被定义。接口提供了结构,因此我们知道我们的代码需要做什么。
回到我们的 TaskController.php文件,我们实例化一个仓库并将Task模型传递给它。
<?php
namespace App\Http\Controllers;
use App\Task;
use App\Repositories\Repository;
use Illuminate\Http\Request;
class TaskController extends Controller
{
// 我们可以从中使用存储库的空间
protected $model;
public function __construct(Task $task)
{
// 设置模型
$this->model = new Repository($task);
}
public function index()
{
return $this->model->all();
}
public function store(Request $request)
{
$this->validate($request, [
'body' => 'required|max:500'
]);
// 创建记录并仅传递可写入的字段
return $this->model->create($request->only($this->model->getModel()->fillable));
}
public function show($id)
{
return $this->model->show($id);
}
public function update(Request $request, $id)
{
// 更新模型并仅传递可写入字段
$this->model->update($request->only($this->model->getModel()->fillable), $id);
return $this->model->find($id);
}
public function destroy($id)
{
return $this->model->delete($id);
}
}
Laravel 服务容器将自动解析我们的依赖项并将其注入到控制器实例中(docs).
至此,我们的应用程序的工作原理完全相同,但是我们的代码已重构为使用苍鹭,并且我们添加了两个API端点。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
注意啦! 审阅翻译的时候,发现代码中有加粗的标志,像下面这样的,然后,我就去追溯了下原文,发现并没有这些东西。
烦请提交翻译和翻译的人员注意一下,我们的代码片段有自己的高亮方式,不要把这个不必要的格式加进入,影响观看。
@MasterShu 提交翻译人员比较随意随意,文章格式错乱了。
也是我权限放太开了,自我检讨下。以后发布的每篇翻译我都会严格审阅。
很多时候,别人(你的老板、你的用户、你的同事)是从作品来判断你优秀与否。这里的作品不止是代码,有时候只是一篇文章一段文字。一个事物,只要是我们经手的,都应该金光闪闪。
希望与君共勉。
这篇翻译文章是我提交的 这里先道个歉 我只是做了个简单的分块处理 确实没有关注排版问题(其实就是没用心) 感谢指出 @MasterShu @Summer
@MasterShu @Remember @Summer 抱歉 默默检讨下。。。下次一定注意。。
@Summer
社区大了,肯定不是一个人可以审阅的过来的,这个大佬不必自责。
@Thans @Remember
其实大家作为见习版主,有一部分也是为了积分,我也是这样,希望大家能一起维护好我们的社区。以前我也出现过类似的问题,不过正好是本人翻译的文章,所以及时纠正了。大家在每个人都在各自的环节都稍微用点儿心,社区肯定会越来越好的。
人人都参与进来,而不是机械的翻译,这个也是技术精进的过程。和大家共勉哈。不要把责任都压在管理员 Summer 身上。作为版主,这点儿责任还是要一起承担的。