为什么要学习Repository Pattern(仓库模式)

Repository 模式主要思想是建立一个数据操作代理层,把controller里的数据操作剥离出来,这样做有几个好处:

  • 把数据处理逻辑分离使得代码更容易维护
  • 数据处理逻辑和业务逻辑分离,可以对这两个代码分别进行测试
  • 减少代码重复
  • 降低代码出错的几率
  • 让controller代码的可读性大大提高

然而,据很多同学反应,这一部分很难学。确实,要独立一个操作层出来,确实会增加大量代码,非常繁琐。如果你是小项目,未必需要使用这一模式。但如果是4-5年以上的复杂大型项目,这种模式的好处就比较明显了。

如果你是纯新手,建议你暂时不要往下看,先把laravel用得比较熟练后再回来学习。

学习Repository Pattern的意义不只是为了使用它,更会让你深入思考框架的分层思想,你开始不仅关注怎么使用一个框架,还会想了解怎样设计一个框架,也许会成为你往高阶段编程的入口。

什么是Repository Pattern

虽然说设计模式和语言及框架无关,但是脱离了语言及框架,我们很难理解,所以我们还是在laravel的语境下来学习吧:

public function index()
{
$posts = Post::whereIn('category_id',[,])->where('is_draft',)->orderBy('created_at', 'desc')->take()->get();
return view('front.index',compact('posts'));
}

以上是典型的Eloquent数据查询代码,如果你编程经验丰富,你会发现这种代码在控制器里到处都是,而且有很多是重复的,可读性很差;我们的目标是把它精简:

仔细观察

  1. Post::whereIn('category_id',[1,2])->where('is_draft',0)->orderBy('created_at', 'desc')->take(5)->get();

其实它由3部分组成,第一是Post,数据模型;第二个是whereIn('category_id',[1,2])->where('is_draft',0)->orderBy('created_at', 'desc')->take(5),数据操作条件;第三个是get(),数据获取的方法;

我们知道,Eloquent里有个Query Scope,可以用来把第二部分,也就是查询条件精简。所以,在使用了Query Scope后,我们可以把精简成:

  1. Post::ofCategory([1,2])->isDraft()->orderBy('created_at', 'desc')->take(5)->get();

咋一看上去,好像也没怎么精简啊,但实际上你已经实现代码解耦和复用了,比如说isDraft(), 这个代码可以到处用,而不用担心耦合问题。

精简程度和你的逻辑抽象程度有关,比如说你完全可以写成:

  1. Post::findPosts([1,2],0,'desc',5)->get();

在轻型项目中,强烈推荐使用Query Scope,这是一种良好的编程习惯。

在更复杂的项目中,Query Scope就不够用了,因为它和数据模型还是一种强耦合,Repository Pattern就是要把第一,第二,第三部分全部解耦;

说到解耦,我们在Laravel的文档攻略中讲过,第一神器就是PHP中的接口(Interface),下面来看例子:

第一步——建立文件夹

  • app

    • Repositories
    • Interfaces
    • Implements

Interfaces里面用来放接口,Implements用来放接口的实现;

第二步——建立一个接口

在上面的Interfaces目录新建一个文件PostInterface.php:

namespace App\Repositories\Interfaces;
Interface PostInterface{
public function findPosts(Array $cat_id,$is_draft,$order,$take){
}
}

第三步——建立一个接口对应的实现

在上面的Implements目录新建一个文件PostRepository.php:

namespace App\Repositories\Implements;
use Post;
class PostRepository Implements PostInterface{
public function findPosts(Array $cat_id,$is_draft,$order,$take){
$query = Post::whereIn('category_id',$cat_id)->where('is_draft',$is_draft)->orderBy('created_at', $order)->take($take)->get();
return $query;
}
}

看这里,很明显,仓库指的就是一个仓库接口的实现;这里定义你的业务逻辑;

第四步——在ServiceProvider中绑定接口

打开app/Providers/AppServiceProvider, 在register()加入代码:

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
}
public function register()
{
$this->app->bind('App\Repositories\Interfaces\PostInterface', 'App\Repositories\Implements\PostRepository');
}
}

我们知道,ServiceProvider是Laravel IOC容器实现动态换接口实现的地方,所以我们在这里绑定一下,这样我们在使用的时候,不直接使用接口实现,而是用ioc容器解析接口,它会帮你自动找到对应好的实现。 这就意味着,以后需要更换实现,可以在这里更换;

第五步——使用仓库

回到我们的controller里来:

use App\Repositories\Interfaces\PostInterface;
class PostController extends BaseController{
public function __construct(PostInterface $post){
$this->postRepo = $post;
}
public function index(){
$this->postRepo->findPosts([,],,'desc',);
}
}

这样你看,第一,我们的业务逻辑变得非常精简,完全不用管查询;第二,现实了数据查询部分的解耦;

到这里,有同学就会问了,一开始说好的三个部分解耦呢,你这里只实现了第二部分啊;

确实,为了最快让大家明白什么是Repository,我把第一和第二部分的解耦省略了,我们放到这篇文章的系列后续讲。

你或许还有不少疑惑,我费那么大劲,写成最后这个样子,好像也没什么区别啊。聪明的同学可能想到一点,如果采用Repository Pattern的话,是不是意味着以后我可以先在controller里写成$this->postRepo->findPosts([1,2],0,'desc',5); 具体的查询逻辑先不写,然后我快速先把 整个应用的业务逻辑先跑一遍,然后再回头一个一个写接口实现来支持业务逻辑;(哇擦,太NB了,妈妈再也不用担心SB客户/PM改变需求了);

恭喜,你已经进入高级编程里说的DDD(Domain Driven Design 领域驱动设计)大门了,事实上,整个Laravel框架的核心架构就是这样干的,IOC+接口,我们会在后续系列文章里介绍;

转载:http://www.cnblogs.com/zhangwei595806165/p/5735959.html

Laravel与Repository Pattern(仓库模式)的更多相关文章

  1. laravel 5.5 仓库模式 文件之间接口与实现操作

    仓库模式 最直接的意思就是: Eloquent数据(数据库)查询  方便快捷,简单明了.自己怎么写的,就怎么去调用,完全ok~ 本质意思: 仓库就像是业务内部的数据对象集合,负责协调业务和数据映射层之 ...

  2. How To Use The Repository Pattern In Laravel

    The Repository Pattern in Laravel is a very useful pattern with a couple of great uses. The first us ...

  3. Laravel Repository Pattern

    Laravel Repository Pattern   The Repository Pattern can be very helpful to you in order to keep your ...

  4. Thinking In Design Pattern——MVP模式演绎

    原文<Thinking In Design Pattern——MVP模式演绎>不知为何丢失了,故重新整理了一遍. 目录 What Is MVP Domain Model StubRepos ...

  5. 学习笔记之ASP.NET MVC & MVVM & The Repository Pattern

    ASP.NET MVC | The ASP.NET Site https://www.asp.net/mvc ASP.NET MVC gives you a powerful, patterns-ba ...

  6. Follow me to learn what is repository pattern

    Introduction Creating a generic repository pattern in an mvc application with entity framework is th ...

  7. Generic repository pattern and Unit of work with Entity framework

    原文 Generic repository pattern and Unit of work with Entity framework Repository pattern is an abstra ...

  8. Using the Repository Pattern with ASP.NET MVC and Entity Framework

    原文:http://www.codeguru.com/csharp/.net/net_asp/mvc/using-the-repository-pattern-with-asp.net-mvc-and ...

  9. Provider Pattern提供者模式和策略模式

    http://www.codeproject.com/Articles/18222/Provider-Pattern Introduction Provider pattern is one of t ...

随机推荐

  1. oracle的特殊权限s bit丢失

    在SUN Cluster搭建过程中,主机工程师在配置集群资源组时报一个oracle的文件权限错误: 协助排查,发现报错很明确,直接指出说oracle的s bit 权限未设置. 直接去查看$ORACLE ...

  2. DataTable与DTO对象的简易转换类

    在web开发过程中,有时候为了数据传输的方便,比如:后台需要更新前端的ViewModel,此时我们定义一个与前端ViewModel结构一样的DTO对象,从数据层获取数据后,将数据封装成DTO然后序列化 ...

  3. JAVA/GUI程序之记事本

    自上半年JAVA课程结束后,再也没有看过JAVA了,最近不是很忙,又简单的看了看,本博客纯属记录学习过程,请大神们别笑,其中错误是难免的,毕竟是新手写的博客.下面就进入我们的正题吧,复习GUI时,就想 ...

  4. 学C#之设计模式系列笔记(1)策略模式

    一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...

  5. java环境搭建和写出一个Helloworld

    一.安装环境和配置环境变量(必要环节) 安装java并配置环境变量 :在"系统变量"中设置3项属性,JAVA_HOME,PATH,CLASSPATH(大小写无所谓),若已存在则点击 ...

  6. ASP.NET MVC搭建项目后台UI框架—1、后台主框架

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  7. Java三大框架之——Hibernate关联映射与级联操作

    什么是Hibernate中的关联映射? 简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射. 它将数据库中的表映射成对应的 ...

  8. Vue.js 入门指南之“前传”(含sublime text 3 配置)

    题记:关注Vue.js 很久了,但就是没有动手写过一行代码,今天准备入手,却发现自己比菜鸟还菜,于是四方寻找大牛指点,才终于找到了入门的“入门”,就算是“入门指南”的“前传”吧.此文献给跟我一样“白痴 ...

  9. JVM调优总结

    堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作 ...

  10. mybatis hibernate比较

    开发速度: 如果一个项目中用到的复杂的查询基本没有,就是简单的增删该查,这样选择hibernate效率就很快了,因为基本的sql语句已经被封装好了,根本不用去写sql语句,但是对于一个大型项目,复杂语 ...