核心概念 —— 契约(Contracts)
Laravel中的契约是指框架提供的一系列定义核心服务的接口。 例如 , 每一个契约都有框架提供的相应实现。例如,Laravel为队列提供了多个驱动的实现,邮件则由 SwiftMailer驱动 实现 。
所有Laravel契约都有其对应的GitHub库,这为所有有效的契约提供了快速入门指南,同时也可以作为独立、解耦的包被包开发者使用。 Laravel门面为Laravel服务的使用提供了便捷方式——不再需要从服务容器中类型提示和契约 解析即可直接通过静态门面调用 。有些开发者喜欢这种便捷,不过也有开发者倾向于使用契约,他们喜欢定义明确的依赖。 注:大多数应用中,不管你使用门面还是契约,合适就好。不过,如果你是在构建一个扩展包,那么就应该使用契约,因为这在扩展包中更容易测试。 正如上面所讨论的,大多数情况下使用契约还是门面取决于个人或团队的喜好,契约和门面都可以用于创建强大的、测试友好的Laravel应用。只要你保持类的职责单一,你会发现使用契约和门面并没有什么实质性的差别。
但是,对契约你可能还是有些疑问。例如,为什么要全部使用接口?使用接口是不是更复杂?下面让我们从两个方面来扒一扒为什么使用接口:松耦合和简单。 首先,让我们看看一些缓存实现的紧耦合代码:
在这个类中,代码和给定缓存实现紧密耦合,由于我们基于一个来自包的具体的缓存类,如果包的API变了,那么相应的,我们的代码必须做修改。 类似的,如果我们想要替换底层的缓存技术(Memcached)为别的技术实现(Redis),我们将再一次不得不修改我们的代码库。我们的代码库应该并不知道谁提供的数据或者数据是怎么提供的。 我们可以基于一种简单的、与提供者无关的接口来优化我们的代码,从而替代上述那种实现:
现在代码就不与任何特定提供者耦合,甚至与Laravel都是无关的。由于契约包不包含任何实现和依赖,你可以轻松的为给定契约编写可选实现代码,你可以随意替换缓存实现而不用去修改任何缓存消费代码。 当所有Laravel服务都统一在简单接口中定义,很容易判断给定服务提供的功能。契约可以充当框架特性的简明文档。 此外,基于简单接口,代码也更容易理解和维护。在一个庞大而复杂的类中,与其追踪哪些方法是有效的,不如转向简单、干净的接口。 那么,如何实现契约呢?这很简单。 Laravel中很多类都是通过服务容器进行解析,包括控制器,以及监听器、中间件、队列任务,甚至路由闭包。所以,要实现一个契约,需要在解析类的构造函数中类型提示这个契约接口。 例如,看看下面这个事件监听器:
事件监听器被解析的时候,服务容器会读取构造函数中的类型提示,并注入适当的值。要学习更多关于服务容器的注册细节,参考其文档。 下面是Laravel契约列表,以及其对应的“门面”: Contract Illuminate\Contracts\Auth\Factory Illuminate\Contracts\Auth\PasswordBroker Illuminate\Contracts\Bus\Dispatcher Illuminate\Contracts\Broadcasting\Broadcaster Illuminate\Contracts\Cache\Repository Illuminate\Contracts\Cache\Factory Illuminate\Contracts\Config\Repository Illuminate\Contracts\Container\Container Illuminate\Contracts\Cookie\Factory Illuminate\Contracts\Cookie\QueueingFactory Illuminate\Contracts\Encryption\Encrypter Illuminate\Contracts\Events\Dispatcher Illuminate\Contracts\Filesystem\Cloud Illuminate\Contracts\Filesystem\Factory Illuminate\Contracts\Filesystem\Filesystem Illuminate\Contracts\Foundation\Application Illuminate\Contracts\Hashing\Hasher Illuminate\Contracts\Logging\Log Illuminate\Contracts\Mail\MailQueue Illuminate\Contracts\Mail\Mailer Illuminate\Contracts\Queue\Factory Illuminate\Contracts\Queue\Queue Illuminate\Contracts\Redis\Database Illuminate\Contracts\Routing\Registrar Illuminate\Contracts\Routing\ResponseFactory Illuminate\Contracts\Routing\UrlGenerator Illuminate\Contracts\Support\Arrayable Illuminate\Contracts\Support\Jsonable Illuminate\Contracts\Support\Renderable Illuminate\Contracts\Validation\Factory Illuminate\Contracts\Validation\Validator Illuminate\Contracts\View\Factory1、简介
Illuminate\Contracts\Queue\Queue
契约定义了队列任务需要实现的方法,Illuminate\Contracts\Mail\Mailer
契约定义了发送邮件所需要实现的方法。
契约(Contracts) VS 门面(Facades)
2、何时使用契约
松耦合
<?php
namespace App\Orders;
class Repository{
/**
* 缓存
*/
protected $cache;
/**
* 创建一个新的Repository实例
*
* @param \SomePackage\Cache\Memcached $cache
* @return void
*/
public function __construct(\SomePackage\Cache\Memcached $cache)
{
$this->cache = $cache;
}
/**
* 通过ID获取订单
*
* @param int $id
* @return Order
*/
public function find($id)
{
if ($this->cache->has($id)) {
//
}
}
}
<?php
namespace App\Orders;
use Illuminate\Contracts\Cache\Repository as Cache;
class Repository{
/**
* 创建一个新的Repository实例
*
* @param Cache $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
}简单
3、如何使用契约
<?php
namespace App\Listeners;
use App\User;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Database;
class CacheOrderInformation
{
/**
* The Redis database implementation.
*/
protected $redis;
/**
* Create a new event handler instance.
*
* @param Database $redis
* @return void
*/
public function __construct(Database $redis)
{
$this->redis = $redis;
}
/**
* Handle the event.
*
* @param OrderWasPlaced $event
* @return void
*/
public function handle(OrderWasPlaced $event)
{
//
}
}
4、契约列表
References Facade
Auth
Password
Bus
Cache
Cache::driver()
Config
App
Cookie
Cookie::queue()
Crypt
Event
File
File
App
Hash
Log
Mail::queue()
Mail
Queue::driver()
Queue
Redis
Route
Response
URL
Validator::make()
View::make()
核心概念 —— 契约(Contracts)的更多相关文章
- Laravel 的核心概念
工欲善其事,必先利其器.在开发Xblog的过程中,稍微领悟了一点Laravel的思想.确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Larav ...
- Laravel 核心概念
工欲善其事,必先利其器.在开发Xblog的过程中,稍微领悟了一点Laravel的思想.确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Larav ...
- 领域驱动设计(DDD)部分核心概念的个人理解
领域驱动设计(DDD)是一种基于模型驱动的软件设计方式.它以领域为核心,分析领域中的问题,通过建立一个领域模型来有效的解决领域中的核心的复杂问题.Eric Ivans为领域驱动设计提出了大量的最佳实践 ...
- Javascript本质第一篇:核心概念
很多人在使用Javascript之前都至少使用过C++.C#或Java,面向对象的编程思想已经根深蒂固,恰好Javascript在语法上借鉴了Java,虽然方便了Javascript的入门,但要深入理 ...
- [程序设计语言]-[核心概念]-02:名字、作用域和约束(Bindings)
本系列导航 本系列其他文章目录请戳这里. 1.名字.约束时间(Binding Time) 在本篇博文开始前先介绍两个约定:第一个是“对象”,除非在介绍面向对象语言时,本系列中出现的对象均是指任何可以有 ...
- spring技术核心概念纪要
一.背景 springframework 从最初的2.5版本发展至今,期间已经发生了非常多的修正及优化.许多新特性及模块的出现,使得整个框架体系显得越趋庞大,同时也带来了学习及理解上的困难. 本文阐述 ...
- ElasticSearch学习笔记-01 简介、安装、配置与核心概念
一.简介 ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便.支持通过HTTP使用JSON进 ...
- Playmaker Input篇教程之引入的核心概念
Playmaker Input篇教程之引入的核心概念 Playmaker Input引入的核心概念 Playmaker引入了4个核心概念:状态机.动作.变量和事件.了解它们是学习操作Playmaker ...
- Maven的几个核心概念
POM (Project Object Model) 一个项目所有的配置都放置在 POM 文件中:定义项目的类型.名字,管理依赖关系,定制插件的行为等等.比如说,你可以配置 compiler 插件让它 ...
随机推荐
- Linux使用locate命令定位文件
FIND命令 很多Linux用户喜欢使用find命令来查找文件,例如他们通常喜欢这样做: find / -name 'pattern' 确实find的强大功能不仅仅用来查找文件,它能用来定位更加细节的 ...
- Light oj 1214-Large Division (同余定理)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1214 题意很好懂,同余定理的运用,要是A数被B数整除,那么A%B等于0.而A很大,那我 ...
- C#学习笔记(十四):GC机制和弱引用
垃圾回收(GC) 垃圾回收即Garbage Collector,垃圾指的是内存中已经不会再使用的对象,通过收集释放掉这些对象占用的内存. GC以应用程序的root为基础,遍历应用程序在Heap上动态分 ...
- c++地址对齐
在一些计算机上,由于性能方面的原因,2个字节的变量,必须放在2的倍数的地址中,4个字节的,就必须放在4的倍数中的地址中,以此类推. 也就是说,如果有3个占用两个字节的变量,分别为:A,B,C,如下图: ...
- 2015南阳CCPC A - Secrete Master Plan 水题
D. Duff in Beach Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description Master Mind KongMing gave ...
- 为TListBox添加水平滚动条
为TListBox添加水平滚动条 实例说明 TListBox组件是一个较为常用的列表组件,在默认情况下该组件是没有水平滚动条的,所以文字过长会显示不完全,在文字较短的情况下还可以,但是如果一行的文字很 ...
- Nginx 1.4.7图片缓存服务器
软件包版本: Nginx 1.4.7 Ngx_cache_purge-2.0 Openssl-1.0.1 Pcre-8.32 二.安装编译: a) 下载pcre-8.32.tar.gz ...
- int a[5]={}, &a+1与(int*)a+1的区别
#include <iostream> #include <typeinfo> using namespace std; int main() { int b, *pb; ch ...
- [原创,分享]DbHelper 续
一直在想怎么样才能让dbHelper更简单,更灵活,更僵化.终于我发布了第一个开源版本的dbhelper.此helper将使用System.Data.DbHelper作为命名空间.采用内部驱动与内容S ...
- 1050. String Subtraction (20)
this problem is from PAT, which website is http://pat.zju.edu.cn/contests/pat-a-practise/1050. firs ...