第3章 解析框架核心設(shè)計(jì)模式
3.1 探索 Facade 實(shí)現(xiàn)原理
什么是 Facade ?
Facade 即門面模式,又被稱為代理模式,當(dāng)應(yīng)用程序需要與容器中的對(duì)象打交道時(shí),就可通過(guò)門面(Facade ) 對(duì)象來(lái)獲取容器內(nèi)部中的具體對(duì)象。相當(dāng)于是通過(guò)一個(gè)第三方類和容器中對(duì)象進(jìn)行通訊。 門面類實(shí)現(xiàn)了應(yīng)用程序與容器之間的解耦,要想實(shí)現(xiàn)門面類的特性,需要先實(shí)現(xiàn)一個(gè)抽象門面的基類,然后通過(guò) getFacadeAccessor( ) 返回對(duì)應(yīng)實(shí)現(xiàn)門面類的別名,而這別名就可直接用于在容器中去提取出對(duì)應(yīng)的類對(duì)象,供應(yīng)用程序使用。
3.2 理解中間件實(shí)現(xiàn)本質(zhì) Pipeline
什么是 Pipeline 模式 ?
管道模式用于將復(fù)雜的過(guò)程分解成多個(gè)獨(dú)立的子任務(wù)。那這每個(gè)子任務(wù)是誰(shuí)來(lái)完成呢?在框架中每個(gè)任務(wù)的執(zhí)行是通過(guò)中間件來(lái)完成對(duì)請(qǐng)求的過(guò)濾執(zhí)行操作。 怎么實(shí)現(xiàn)的?把中間件放到數(shù)組中,然后基于 array_reduce() 函數(shù),把數(shù)組中的每個(gè)中間件,回調(diào)到閉包函數(shù)中進(jìn)行執(zhí)行,最后得到處理后的結(jié)果 相當(dāng)于咱們喝的飲用水一樣,開始有雜質(zhì)的水會(huì)流入到過(guò)濾得管道,管道中存在過(guò)濾網(wǎng)、 晴綸綿 、 石英砂、 柱狀活性炭 等東西。雜質(zhì)的水只有通過(guò)它們后,才能得到純凈水。
3.3 分析契 Contracts 設(shè)計(jì)
什么是 Contracts 模式 ?
契約本質(zhì)就是接口,用來(lái)定義相關(guān)類庫(kù)的功能職責(zé),從而約束類的功能職責(zé)和定義標(biāo)準(zhǔn)。 Laravel 中許多功能類都是通過(guò) 服務(wù)容器 解析出來(lái)的,包括控制器、事件監(jiān)聽(tīng)器、中間件、任務(wù)隊(duì)列,甚至路由閉包。因?yàn)樵谌萜髯⑷霑r(shí),會(huì)采用關(guān)鍵字來(lái)綁定,接口與類的關(guān)系。而類又會(huì)實(shí)現(xiàn)接口,這樣方法的類型約束為接口時(shí),只要實(shí)現(xiàn)了這個(gè)接口的類,都是可以別注入到對(duì)象中。 所以,通過(guò)一個(gè)契約的實(shí)現(xiàn),只需要在被解析類的構(gòu)造函數(shù)中添加「類型提示」即可得到對(duì)象。因?yàn)槁酚山馕鐾瓿珊螅绦驎?huì)執(zhí)行控制器,而在執(zhí)行控制器的時(shí)候,也會(huì)通過(guò)容器的 make 方法先拿到容器中的對(duì)象,當(dāng)然這里就會(huì)通過(guò)反射機(jī)制來(lái)實(shí)例化控制器啦。而控制器中調(diào)用方法里面約束要傳入的對(duì)象,也會(huì)通過(guò) ReflectionMethod 進(jìn)行反射創(chuàng)建實(shí)例給到我們控制器需要的對(duì)象。最后可以直接調(diào)用方法來(lái)執(zhí)行業(yè)務(wù)操作啦。
3.4 解密服務(wù)提供者
什么是服務(wù)提供者 ?
服務(wù)提供者,在 Laravel 里面,本質(zhì)就是一個(gè)工廠類。用它來(lái)進(jìn)行服務(wù)綁定。當(dāng)我們需要綁定一個(gè)或多個(gè)服務(wù)的時(shí)候,就可以自定義一個(gè)服務(wù)提供者,然后把服務(wù)綁定的邏輯都放在該類中實(shí)現(xiàn)。然后框架在進(jìn)程初始化引導(dǎo)時(shí),就會(huì)調(diào)用相關(guān)服務(wù)注冊(cè)者的 register 來(lái)完整注冊(cè)。 在 Laravel 里面,要自定義一個(gè)服務(wù)提供者,只要繼承 Illuminate\Support\ServiceProvider 這個(gè)類即可。 //laraveldemo\vendor\laravel\framework\src\Illuminate\Support\ServiceProvider.php app->singleton('s1', function(){ ??return 'class_Service1'; }); $this->app->singleton('s2', function(){ ??return 'class_Service2'; }); $this->app->singleton('s3', function(){ ??return 'class_Service3'; }); ?} ? ??public?function provides() ?{ return ['s1','s2','s3']; ?} } 3.5 洞察組件化實(shí)現(xiàn)原理
1. 組件化的前身 ?
在沒(méi)有組件化時(shí),開發(fā)對(duì)應(yīng)的業(yè)務(wù)功能都會(huì)寫在一起,而且功能只能讓自己的業(yè)務(wù)模塊來(lái)使用,如果后面有相似的項(xiàng)目就沒(méi)法做到快速移植,還需要重新開發(fā)一次。
2. 什么是組件化 ?
把一些通用的功能或業(yè)務(wù)以組件化的方式進(jìn)行抽離,相當(dāng)于插拔式的效果,需要使用組件時(shí),直接插入到框架中來(lái)。后面不同的項(xiàng)目或業(yè)務(wù)需要使用到對(duì)應(yīng)的功能或業(yè)務(wù)模塊時(shí),都可直接引入對(duì)應(yīng)的組件,這樣就可以直接復(fù)用到組件中的功能。
3. 怎么選擇組件化 ?
最好是通用的功能或業(yè)務(wù)組件,比如發(fā)布功能,如果只想單獨(dú)寫一個(gè)發(fā)布就算了,那么只能適應(yīng)于當(dāng)前的業(yè)務(wù),但如果根據(jù)組件化的方式進(jìn)行封裝,把發(fā)布和數(shù)據(jù)相關(guān)的存儲(chǔ)操作給抽離出來(lái),然后封裝成組件化,后面就可以直接引用到組件的。 如果是業(yè)務(wù)組件,那么可以把用戶、訂單等模塊給直接提取出來(lái),來(lái)做到封裝。 組件化的根本就是通用方法,有些需要條件的需求可通過(guò)配置私有化,直接進(jìn)行解決。
4. 如何開發(fā)組件呢 ?
根據(jù) composer 來(lái)進(jìn)行組件化的開發(fā),可直接把相關(guān)功能給封裝到類庫(kù)中。
自行組件類庫(kù)封裝,后面項(xiàng)目需要用到這個(gè)功能直接復(fù)制相關(guān)類庫(kù)到項(xiàng)目的共用模塊中