为什么要学习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. CRL快速开发框架系列教程二(基于Lambda表达式查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  2. SharePoint 2013 Create taxonomy field

    创建taxonomy field之前我们首先来学习一下如果创建termSet,原因是我们所创建的taxonomy field需要关联到termSet. 简单介绍一下Taxonomy Term Stor ...

  3. Unity iOS混合开发界面切换思路

    Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...

  4. JQuery Sizzle引擎源代码分析

    最近在拜读艾伦在慕课网上写的JQuery课程,感觉在国内对JQuery代码分析透彻的人没几个能比得过艾伦.有没有吹牛?是不是我说大话了? 什么是Sizzle引擎? 我们经常使用JQuery的选择器查询 ...

  5. ES6笔记(5)-- Generator生成器函数

    系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...

  6. 说一说javascript跨域和jsonp

    同源策略 在浏览器的安全策略中“同源策略”非常如雷贯耳,说的是协议.域名.端口相同则视为同源,域名也可换成IP地址,不同源的页面脚本不能获取对方的数据. 要是想使用XMLHttpRequest或者常规 ...

  7. 【WCF】如何将WCF部署到远程服务器

    一.前言       最近需要将自己写的WCF服务部署到远程服务器上,也就是公网上.宿主是IIS,在配置成功之前遇到了很多问题,问题如下: 1. WCF该怎么宿主在IIS上,为何会出现 400 Bad ...

  8. GET command找不到

    谷歌的: On running a cronjob with get command, I was getting the following error. /bin/sh: GET: command ...

  9. 高性能 TCP & UDP 通信框架 HP-Socket v3.4.1

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  10. 20款 JavaScript 开发框架推荐给前端开发者

    下面,我们给大家提供了一个用于 HTML5 开发的各种用途的 JavaScript 库列表.这些框架能够给前端开发人员提供更好的功能实现的解决方案.如果你有收藏优秀的框架,也可以在后面的评论中分享给我 ...