girolando / repositories-pattern
Laravel Repositories Pattern 实现方案
Requires
- php: >=5.6.0
- illuminate/console: >=5.1
- illuminate/database: >=5.1
- illuminate/filesystem: >=5.1
- illuminate/support: >=5.1
- symfony/class-loader: >=2.3
README
此包允许你在 Laravel 应用程序中实现 Repositories 设计模式。它使得使用服务层变得简单。
##安装 安装非常简单,只需运行
composer require andersonef/repositories-pattern
##服务提供者 你必须在 config/app.php 文件中注册此包的服务提供者。只需在你的 $providers 数组中添加此行
Andersonef\Repositories\Providers\RepositoryProvider::class,
##创建你的仓库和服务:在你的控制台,输入以下命令
php artisan make:repository BlogNamespace/Post --entity=App/Models/Post
请记住使用你实体路径的完整命名空间。如果你使用的是自定义命名空间,请使用
php artisan make:repository BlogNamespace/Post --entity=CustomNamespace/Models/Post
这将在你的 app 目录中创建以下文件结构
app/
Repositories/
BlogNamespace/
PostRepository.php
Services/
BlogNamespace/
PostService.php
##仓库文件结构 你的仓库文件将使用以下代码创建
namespace Inet\Repositories\BlogNamespace; use Andersonef\Repositories\Abstracts\RepositoryAbstract; use \Post; /** * Data repository to work with entity Post. * * Class PostRepository * @package Inet\Repositories\BlogNamespace */ class PostRepository extends RepositoryAbstract{ public function entity() { return \Post::class; } }
##服务文件结构 你的 PostService.php 文件将使用以下代码创建
namespace Inet\Services\BlogNamespace; use Andersonef\Repositories\Abstracts\ServiceAbstract; use Illuminate\Database\DatabaseManager; use \Inet\Repositories\BlogNamespace\PostRepository; /** * Service layer that will applies all application rules to work with Post class. * * Class PostService * @package Inet\Services\BlogNamespace */ class PostService extends ServiceAbstract{ /** * This constructor will receive by dependency injection a instance of PostRepository and DatabaseManager. * * @param PostRepository $repository * @param DatabaseManager $db */ public function __construct(PostRepository $repository, DatabaseManager $db) { parent::__construct($repository, $db); } }
##使用 使用此模式,你可以将应用程序规则与数据访问规则分离,并且可以非常简单的方式重用你的代码。想象一下,你有一个应用程序,用户可以通过公共页面注册,并且管理员可以通过管理员面板注册用户。注册用户的规则在这两种情况下都是相同的,但是管理员面板必须要求管理员登录用户,并且有一个选项可以将新用户发送到支付订阅费用的页面。在旧的方式中,你必须复制代码或使用 Laravel 命令来隔离用户注册规则。使用服务层和仓库模式,你将在 UserService 中编写用户注册规则,并在两个控制器(公共页面注册和管理员面板)中调用 $userService->create($request->all())。如果你必须实现一个从安卓界面保存用户的 API,你可以重用你的服务层,只需更改你的控制器如何响应客户端。
##仓库继承方法:你的仓库有一些从 RepositoryAbstract 类继承的方法。它们是
- create(array $data);:尝试创建一个指定实体的新实例。警告:你的实体必须声明 $fillable 字段
- update(array $data, $id);:更新指定的实体。
- delete($id);:删除指定的实体。
- find($id, array $columns = ['*']);:通过 ID 查找指定实体的实例。
- findBy(array $fields, array $columns = ['*']);:使用字段查找指定实例的集合(见 phpdocs)。
##服务继承方法:你的服务将类似于你的仓库。主要区别是你的服务层必须实现应用程序逻辑,因此它的方法中有事务。
- create(array $data):打开一个事务并尝试使用 $data 数组创建一个实例。你可以覆盖它。
- update(array $data, $id):打开一个事务并尝试使用 $data 数组更新实例。
- delete($id):打开一个事务并尝试删除指定实体的实例。
##魔法方法:为了方便起见,我们可以在服务和仓库类中使用魔法方法。
$yourservice->repositoryMethod(); // this will be the same as: $yourservice->getRepository()->repositoryMethod(); $yourRepository->entityMethod(); // this will be the same as: $tyourRepository->getEntity()->entityMethod();
##使用标准:你可以实现标准以重用你的应用程序查询规则。此包为你提供了一个默认标准,即 FindUsingLikeCriteria。让我们假设你必须在博客上实现一个搜索字段,并且必须返回包含 $query 变量的所有帖子。你可以简单地这样做
$result = $postService->findByCriteria(new FindUsingLikeCriteria($request->get('textQuery')))->paginate(10);
这将返回包含标题、内容或作者与请求属性 'textQuery' 内的文本相似的帖子的集合。您可以创建自己的条件,这非常简单:##创建自己的条件 这将是您的自定义条件
namespace Andersonef\Repositories\Criteria; use Andersonef\Repositories\Abstracts\CriteriaAbstract; use Andersonef\Repositories\Contracts\RepositoryContract; use Illuminate\Database\Eloquent\Model; class UnreadRecentPostsCriteria extends CriteriaAbstract{ public function apply(Model $model, RepositoryContract $repository) { $model ->where('created_at','>',(new \DateTime())->sub(new \DateInterval('P3D'))->format('Y-m-d')) ->where('status_read', '=', 1); return $model; } }
##致谢 本软件包是基于此其他软件创建的: https://github.com/prettus/l5-repository 我仅实现了一些更多选项并对它进行了一些小的修改,以便更好地适应我所工作的公司。