andersonef / repositories-pattern
Laravel 仓库模式实现
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应用程序中实现仓库设计模式。它还使得使用服务层变得简单。
##安装 安装非常简单,只需运行
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())。如果您必须实现一个从Android界面保存用户的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。让我们假设您必须在您的博客上实现一个搜索字段,并且必须获取所有包含一些文本的帖子。您可以简单地进行以下操作
$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 我只是实现了一些更多选项,并对它进行了一些小的修改,使其更适合我所在的公司。