核心概念 —— 门面(Facades)
?
1、簡介
為應(yīng)用的中的綁定類提供了一個“靜態(tài)”接口。 內(nèi)置了很多門面,你可能在不知道的情況下正在使用它們。Laravel 的門面作為中的底層類的“靜態(tài)代理”,相比于傳統(tǒng),在維護(hù)時能夠提供更加易于測試、更加靈活的、簡明且富有表現(xiàn)力的語法。
Laravel的所有門面都定義在 Illuminate\Support\s 命名空間下,所以我們可以輕松訪問到門面:
use Illuminate\Support\Facades\Cache;Route::get('/cache', function () {return Cache::get('key'); });在整個Laravel中,很多例子使用了門面來演示框架的各種功能特性
2、何時使用門面
門面有諸多優(yōu)點,其提供了簡單、易記的語法,讓我們無需記住長長的類名即可使用Laravel提供的功能特性,此外,由于他們對PHP動態(tài)方法的獨特用法,使得它們很容易測試。
但是,使用門面也有需要注意的地方,一個最主要的危險就是類范圍蠕變。由于門面如此好用并且不需要注入,在單個類中使用過多門面,會讓類很容易變得越來越大。使用依賴注入則會讓此類問題緩解,因為一個巨大的構(gòu)造函數(shù)會讓我們很容易判斷出類在變大。因此,使用門面的時候要尤其注意類的大小,以便控制其有限職責(zé)。
注:構(gòu)建與Laravel交互的第三方擴(kuò)展包時,最好注入Laravel契約而不是使用門面,因為擴(kuò)展包在Laravel之外構(gòu)建,你將不能訪問Laravel的門面測試輔助函數(shù)。
門面 vs 依賴注入
依賴注入的最大優(yōu)點是可以替換注入類的實現(xiàn),這在測試時很有用,因為你可以注入一個模擬或存根并且在存根上斷言不同的方法。
但是在靜態(tài)類方法上進(jìn)行模擬或存根卻行不通,不過,由于門面使用了動態(tài)方法對服務(wù)容器中解析出來的對象方法調(diào)用進(jìn)行了代理,我們也可以像測試注入類實例那樣測試門面。例如,給定以下路由:
use Illuminate\Support\Facades\Cache;Route::get('/cache', function () {return Cache::get('key'); });我們可以這樣編寫測試來驗證 Cache::get 方法以我們期望的方式被調(diào)用:
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 輔助函數(shù)
除了門面之外,Laravel還內(nèi)置了許多輔助函數(shù)用于執(zhí)行通用任務(wù),比如生成視圖、觸發(fā)事件、分配任務(wù),以及發(fā)送HTTP響應(yīng)等。很多輔助函數(shù)提供了和響應(yīng)門面一樣的功能,例如,下面這個門面調(diào)用和輔助函數(shù)調(diào)用是等價的:
return View::make('profile'); return view('profile');門面和輔助函數(shù)并不實質(zhì)性差別,使用輔助函數(shù)的時候,可以像測試相應(yīng)門面那樣測試它們。例如,給定以下路由:
Route::get('/cache', function () {return cache('key'); });在調(diào)用底層, cache 方法會去調(diào)用 Cache 門面上的 get 方法,因此,盡管我們使用這個輔助函數(shù),我們還是可以編寫如下測試來驗證這個方法以我們期望的方式和參數(shù)被調(diào)用:
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 應(yīng)用中,門面就是一個為容器中對象提供訪問方式的類。該機(jī)制原理由 Facade 類實現(xiàn)。Laravel 自帶的門面,以及我們創(chuàng)建的自定義門面,都會繼承自 Illuminate\Support\Facades\Facade 基類。
門面類只需要實現(xiàn)一個方法:getFacadeAccessor。正是 getFacadeAccessor 方法定義了從容器中解析什么,然后Facade 基類使用魔術(shù)方法 __callStatic() 從你的門面中調(diào)用解析對象。
下面的例子中,我們將會調(diào)用 Laravel 的緩存系統(tǒng),瀏覽代碼后,也許你會覺得我們調(diào)用了 Cache 的靜態(tài)方法 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 接口的實現(xiàn)。我們對門面的所有調(diào)用都會被傳遞給 Laravel 緩存服務(wù)的底層實例。
如果我們查看 Illuminate\Support\Facades\Cache 類的源碼,將會發(fā)現(xiàn)其中并沒有靜態(tài)方法 get:
class Cache extends Facade{/*** 獲取組件注冊名稱** @return string*/protected static function getFacadeAccessor() { return 'cache'; } }Cache 門面繼承 Facade 基類并定義了 getFacadeAccessor 方法,該方法的工作就是返回服務(wù)容器綁定類的別名,當(dāng)用戶引用 Cache 類的任何靜態(tài)方法時,Laravel 從服務(wù)容器中解析 cache 綁定,然后在解析出的對象上調(diào)用所有請求方法(本例中是 get)。
4、門面類列表
下面列出了每個門面及其對應(yīng)的底層類,這對深入給定根門面的 API 文檔而言是個很有用的工具。服務(wù)容器綁定鍵也被包含進(jìn)來:
門面
類
服務(wù)容器綁定
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)
轉(zhuǎn)載于:https://www.cnblogs.com/zhengyanbin2016/p/6008067.html
總結(jié)
以上是生活随笔為你收集整理的核心概念 —— 门面(Facades)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (计算机组成原理)第五章中央处理器-第三
- 下一篇: (计算机组成原理)第六章总线-第一节:总