1.內容介紹
深入決議tp5.1與laravel 中Facade底層原理實作
1. 什么是Facade
2. 為什么需要有什么好處
3. Facade實作原理
4. 功能實作、
5. 容器注入
2.知識講解
0.什么是Facade??為什么需要?有什么好處
專業解釋:
門面模式(Facade)又稱外觀模式,用于為子系統中的一組介面提供一個一致的界面,門面模式定義了一個高層介面,這個介面使得子系統更加容易使用:引入門面角色之后,用戶只需要直接與門面角色互動,用戶與子系統之間的復雜關系由門面角色來實作,從而降低了系統的耦合度,
通俗解釋:
門面為容器中的類提供了一個靜態呼叫介面,相比于傳統的靜態方法呼叫, 帶來了更好的可測驗性和擴展性,你可以為任何的非靜態類別庫定義一個facade類,
對于一個非靜態的類,如果要呼叫這個類的方法我們可能就是要通過new 創建這個物件,然后再通過 -> 呼叫這個類的方法
如:
我們要呼叫這個類的方法就是
這樣呼叫類,但是如果呼叫的次數多了,自己每次呼叫這方法都要創建類從寫法上就覺得不是很好而我們更多的是想直接以靜態通過類名::方法() 的方式呼叫,并且開發速度不快以及不夠優雅,
而如果我們使用facade模式
給這個類一個靜態代理物件,然后我們就可以通過靜態的方式呼叫
當然如上是TP5手冊的例子
1.自己實踐一次
首先我們可以創建一個工具類UserUtil
如果說我們需要使用這個類的時候,比如:在index控制器中進行呼叫UserUtil中的index方法
如上代碼,這就是我們一般的操作方式,
這樣我們就會看起來不夠的優雅,我在使用的時候還需要new出這個物件,我不想new怎么辦?
我們修改一下UserUtil中的index方法,用static修飾
然后在控制器中,就可以通過類名的方式靜態的呼叫了
但是實際上這樣并不是很好,如果說我們的UserUtil中會定義很多方法,如果說我們的Util中不止一個UserUtil,比如有TreeUtil等等其他類,這個時候我們就需要一一的給這些類定義static很明顯就不夠優雅,同時在記憶體中會一直保存這些靜態屬性,有很多使用其實次數不多但是也會保存很顯然會占用一部分空間和資源,
其實還有一個最大的問題就是擴展和維護不強,
比如我們在做專案的時候我們在1.0版本的時候我們可能會在index方法添加很多代碼,同時又有很多其他的方法,可是有一天產品經理需要改需求,這個時候你發現你定義的這個類沒用了不滿足這個需求的時候那么我們就只有需改原始碼
那么接下來我們就需要對于這個UserUtil中的方法需改,可是當需改一個類的時間比一個新建一個類的時間要多的時候最好的辦法就是重寫,這個時候我們可能在接下來的操作中要需改很多呼叫這個UserUtil的地方,腫么辦??
我們就可以使用fa?ade作為這種類代理,
首先:我們先把UserUtil類中的index需改回來
然后創建一個app\facade\UserUtil.php的門面代理類
在類中繼承Facade,同時重寫think\Facade類中的getFacadeClass方法
在方法中return的值就是 這個類要代理的實際類 你也可以是
return “app\util\UserUtil”;
只是那樣可以顯得高大上哈哈哈~~~
然后我們在控制器中使用
注意!引入的是app\facade\UserUtil
然后就成功了,
在代理類中除了重寫getFacadeClass方法外還可以使用think\Facade的bind方法
首先我們一起看一下tp5.1對于框架是怎么對于核心類別庫用facade代理的
打開thinkphp\base.php這個檔案,就可以發現tp5.1的核心類別庫是通過Think\Facade中的bind方法進行了定義
同時又通過Think\Loader中的addClassAlias方法對于核心類別名注冊
那么我們也可以模仿
首先把app\facade\UserUtil類進行處理
不重寫getFacadeClass方法
然后我們在app\common.php中寫
然后使用
Success
2.Tp5.1決議Facade
執行User::index()時
會進入think\Facade類中
因為沒有實際呼叫的方法這個時候執行__callStatic
通過createFacade創建實際被代理類的實體
首先判斷是否創建過
執行子類重寫的定義被代理類的方法
如果沒有重寫定義這個被代理類的地址
這個時候就檢查是否被系結
重邦定的$bind中獲取實體
創建實體并執行實體的方法
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/108988.html
標籤:PHP
