1、简介

为应用的中的绑定类提供了一个“静态”接口。 内置了很多门面,你可能在不知道的情况下正在使用它们。Laravel 的门面作为中的底层类的“静态代理”,相比于传统,在维护时能够提供更加易于测试、更加灵活的、简明且富有表现力的语法。

Laravel的所有门面都定义在 Illuminate\Support\s 命名空间下,所以我们可以轻松访问到门面:

use Illuminate\Support\Facades\Cache;Route::get('/cache', function () {return Cache::get('key');
});

在整个Laravel中,很多例子使用了门面来演示框架的各种功能特性

2、何时使用门面

门面有诸多优点,其提供了简单、易记的语法,让我们无需记住长长的类名即可使用Laravel提供的功能特性,此外,由于他们对PHP动态方法的独特用法,使得它们很容易测试。

但是,使用门面也有需要注意的地方,一个最主要的危险就是类范围蠕变。由于门面如此好用并且不需要注入,在单个类中使用过多门面,会让类很容易变得越来越大。使用依赖注入则会让此类问题缓解,因为一个巨大的构造函数会让我们很容易判断出类在变大。因此,使用门面的时候要尤其注意类的大小,以便控制其有限职责。

注:构建与Laravel交互的第三方扩展包时,最好注入Laravel契约而不是使用门面,因为扩展包在Laravel之外构建,你将不能访问Laravel的门面测试辅助函数。

门面 vs 依赖注入

依赖注入的最大优点是可以替换注入类的实现,这在测试时很有用,因为你可以注入一个模拟或存根并且在存根上断言不同的方法。

但是在静态类方法上进行模拟或存根却行不通,不过,由于门面使用了动态方法对服务容器中解析出来的对象方法调用进行了代理,我们也可以像测试注入类实例那样测试门面。例如,给定以下路由:

use Illuminate\Support\Facades\Cache;Route::get('/cache', function () {return Cache::get('key');
});

我们可以这样编写测试来验证 Cache::get 方法以我们期望的方式被调用:

use Illuminate\Support\Facades\Cache;/*** A basic functional test example.** @return void*/
public function testBasicExample()
{Cache::shouldReceive('get')->with('key')->andReturn('value');$this->visit('/cache')->see('value');
}
门面 vs 辅助函数

除了门面之外,Laravel还内置了许多辅助函数用于执行通用任务,比如生成视图、触发事件、分配任务,以及发送HTTP响应等。很多辅助函数提供了和响应门面一样的功能,例如,下面这个门面调用和辅助函数调用是等价的:

return View::make('profile');
return view('profile');

门面和辅助函数并不实质性差别,使用辅助函数的时候,可以像测试相应门面那样测试它们。例如,给定以下路由:

Route::get('/cache', function () {return cache('key');
});

在调用底层, cache 方法会去调用 Cache 门面上的 get 方法,因此,尽管我们使用这个辅助函数,我们还是可以编写如下测试来验证这个方法以我们期望的方式和参数被调用:

use Illuminate\Support\Facades\Cache;/*** A basic functional test example.** @return void*/
public function testBasicExample()
{Cache::shouldReceive('get')->with('key')->andReturn('value');$this->visit('/cache')->see('value');
}
3、门面工作原理

在 Laravel 应用中,门面就是一个为容器中对象提供访问方式的类。该机制原理由 Facade 类实现。Laravel 自带的门面,以及我们创建的自定义门面,都会继承自 Illuminate\Support\Facades\Facade 基类。

门面类只需要实现一个方法:getFacadeAccessor。正是 getFacadeAccessor 方法定义了从容器中解析什么,然后Facade 基类使用魔术方法 __callStatic() 从你的门面中调用解析对象。

下面的例子中,我们将会调用 Laravel 的缓存系统,浏览代码后,也许你会觉得我们调用了 Cache 的静态方法 get

<?phpnamespace App\Http\Controllers;use Cache;
use App\Http\Controllers\Controller;class UserController extends Controller{/*** 为指定用户显示属性** @param  int  $id* @return Response*/public function showProfile($id){$user = Cache::get('user:'.$id);return view('profile', ['user' => $user]);}
}

注意我们在顶部位置引入了 Cache 门面。该门面作为代理访问底层 Illuminate\Contracts\Cache\Factory 接口的实现。我们对门面的所有调用都会被传递给 Laravel 缓存服务的底层实例。

如果我们查看 Illuminate\Support\Facades\Cache 类的源码,将会发现其中并没有静态方法 get

class Cache extends Facade{/*** 获取组件注册名称** @return string*/protected static function getFacadeAccessor() { return 'cache'; }
}

Cache 门面继承 Facade 基类并定义了 getFacadeAccessor 方法,该方法的工作就是返回服务容器绑定类的别名,当用户引用 Cache 类的任何静态方法时,Laravel 从服务容器中解析 cache 绑定,然后在解析出的对象上调用所有请求方法(本例中是 get)。

4、门面类列表

下面列出了每个门面及其对应的底层类,这对深入给定根门面的 API 文档而言是个很有用的工具。服务容器绑定键也被包含进来:

门面

服务容器绑定

App

app

Artisan

artisan

Auth

auth

Blade

blade.compiler

Bus

Cache

cache

Config

config

Cookie

cookie

Crypt

encrypter

DB

db

DB (Instance)

Event

events

File

files

Gate

Hash

hash

Lang

translator

Log

log

Mail

mailer

Password

auth.password

Queue

queue

Queue (Instance)

queue

Queue (Base Class)

Redirect

redirect

Redis

redis

Request

request

Response

Route

router

Schema

Session

session

Session (Instance)

Storage

filesystem

URL

url

Validator

validator

Validator (Instance)

View

view

View (Instance)

转载于:https://www.cnblogs.com/zhengyanbin2016/p/6008067.html

核心概念 —— 门面(Facades)相关推荐

  1. php框架所用到的核心概念,【PHP】PHP现代框架代表-Laravel框架核心技术特性

    一.php语言特点及发展现状 1.服务端脚本语言,自由度太大 ,一个业务逻辑可言写在模型里,控制器里,也可以单独封装成一个类,甚至可以嵌入到html里,这样势必会造成混乱,业务逻辑散落在各处,尤其对于 ...

  2. Laravel的核心概念

    工欲善其事,必先利其器.在开发Xblog的过程中,稍微领悟了一点Laravel的思想.确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Larav ...

  3. SSM Chapter 05 Spring 核心概念

    SSM Chapter 05 Spring 核心概念 笔记 本章目标: 理解Spring IoC的原理 掌握Spring IoC的配置 理解Spring AOP的原理 掌握Spring AOP的配置 ...

  4. 2021年大数据ELK(五):Elasticsearch中的核心概念

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 Elasticsearch中的核心概念 一.索引 index 二 ...

  5. Sg.js框架核心概念

    Sg.js框架核心概念: 1)所有变量.方法.类对象全部都是从属于$g主树,由$g分支出很多$g.变量名.$g.方法.$g.对象id.$g.类: 2)获取控件内部属性必须使用公开的get方法获取,禁止 ...

  6. 学习 JavaScript (四)核心概念:操作符

    JavaScript 的核心概念主要由语法.变量.数据类型.操作符.语句.函数组成,前面三个上一篇文章已经讲解完了.后面三个内容超级多,这篇文章主要讲解的是操作符. 操作符 什么叫做操作符? 这是一种 ...

  7. Go modules基础精进,六大核心概念全解析(下)

    Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go Modules六大核心概念,包括了设计理念与兼容性原则等,掌握这些技术点对于管理和维护Go 模块有 ...

  8. Go modules基础精进,六大核心概念全解析(上)

    Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go Modules六大核心概念,包括了设计理念与兼容性原则等,掌握这些技术点对于管理和维护Go 模块有 ...

  9. Maven学习总结(四)——Maven核心概念

    2019独角兽企业重金招聘Python工程师标准>>> Maven学习总结(四)--Maven核心概念 一.Maven坐标 1.1.什么是坐标? 在平面几何中坐标(x,y)可以标识平 ...

最新文章

  1. display:inline-block 的使用
  2. 网站SEO优化技巧的“减法运算”
  3. python基础之if、while、for语句
  4. gradle 打war 包以及合并jar包
  5. matlab迭代次数,怎么知道程序中的迭代次数呢
  6. 【ElasticSearch】Es 源码之 CleanerService 源码解读
  7. 在python中、下列代码的输出是什么-智慧树知到《Python程序设计基础》章节测试答案...
  8. javaeye API
  9. 如何在软件UI设计中运用格式塔心理学5项法则?
  10. matlab矩阵处理实验报告,MATLAB矩阵实验报告.doc
  11. 小众软件(持续更新)
  12. 【代码重构(Refectoring)系列教程】基本型别偏执(Primitive Obsession)
  13. python语言开发什么_python语言是什么语言开发的_Python语言的由来,编程语言简史...
  14. 【coq】函数语言设计 笔记 03 - list
  15. LOJ#6198. 谢特 SAM+启发式合并+01trie
  16. 【微信退款】Java实现微信APP退款和JSAPI退款流程
  17. 2018web前端不好找工作之web前端面试简历补救篇
  18. Android NavigationBar 显示 Menu 按键
  19. Keras安装+Pycharm配置Keras
  20. 基于深度学习的人脸检测和关键点检测推理实践(OpenCV实现,含代码)

热门文章

  1. XStream xml与javabean之间的互转
  2. Linux运维 第三阶段 (二) DHCP
  3. .NET种Json时对单引号和特殊字符串的处理
  4. SBO中流程控制功能的实现-SBO_SP_TransactionNotification
  5. EXCEL_CLASS
  6. 每日一个css效果之css sprites
  7. PHP如何批量更新MYSQL中的数据
  8. Windows 7 提示AtBroke.exe初始化失败
  9. 《敏捷企业》作者访谈录
  10. iOS之widget开发(Today Extension)