laravel的核心是服務(wù)容器,也就是IOC容器。該容器提供了整個框架中需要的一系列服務(wù),其中包含了依賴注入和控制反轉(zhuǎn)兩部分,控制反轉(zhuǎn)是面向對象編程中的一種設(shè)計原則,可以用來減低計算機代碼之間的耦合度。
本文操作環(huán)境:Windows10系統(tǒng)、Laravel6版、Dell G3電腦。
laravel的核心是什么
服務(wù)容器,也叫IOC容器,其實包含了依賴注入(DI)和控制反轉(zhuǎn)(IOC)兩部分,是laravel的真正核心。其他的各種功能模塊比如?Route(路由)、Eloquent?ORM(數(shù)據(jù)庫?ORM?組件)、Request?and?Response(請求和響應(yīng))等等等等,實際上都是與核心無關(guān)的類模塊提供的,這些類從注冊到實例化,最終被你所使用,其實都是?laravel?的服務(wù)容器負責(zé)的。服務(wù)容器這個概念比較難解釋清楚,只能一步步從服務(wù)容器的產(chǎn)生歷史慢慢解釋
該容器提供了整個框架中需要的一系列服務(wù)。
IoC?容器誕生的故事——石器時代(原始模式)
我們把一個“超人”作為一個類,
class?Superman?{}
我們可以想象,一個超人誕生的時候肯定擁有至少一個超能力,這個超能力也可以抽象為一個對象,為這個對象定義一個描述他的類吧。一個超能力肯定有多種屬性、(操作)方法,這個盡情的想象,但是目前我們先大致定義一個只有屬性的“超能力”,至于能干啥,我們以后再豐富:
class?Power?{ ????/** ?????*?能力值 ?????*/ ????protected?$ability; ????/** ?????*?能力范圍或距離 ?????*/ ????protected?$range; ????public?function?__construct($ability,?$range) ????{ ????????$this->ability?=?$ability; ????????$this->range?=?$range; ????} }
這時候我們回過頭,修改一下之前的“超人”類,讓一個“超人”創(chuàng)建的時候被賦予一個超能力:
class?Superman { ????protected?$power; ????public?function?__construct() ????{ ????????$this->power?=?new?Power(999,?100); ????} }
這樣的話,當我們創(chuàng)建一個“超人”實例的時候,同時也創(chuàng)建了一個“超能力”的實例,但是,我們看到了一點,“超人”和“超能力”之間不可避免的產(chǎn)生了一個依賴。
所謂“依賴”,就是“我若依賴你,少了你就沒有我”。
在一個貫徹面向?qū)ο?/b>編程的項目中,這樣的依賴隨處可見。少量的依賴并不會有太過直觀的影響,我們隨著這個例子逐漸鋪開,讓大家慢慢意識到,當依賴達到一個量級時,是怎樣一番噩夢般的體驗。當然,我也會自然而然的講述如何解決問題。
之前的例子中,超能力類實例化后是一個具體的超能力,但是我們知道,超人的超能力是多元化的,每種超能力的方法、屬性都有不小的差異,沒法通過一種類描述完全。我們現(xiàn)在進行修改,我們假設(shè)超人可以有以下多種超能力:
飛行,屬性有:飛行速度、持續(xù)飛行時間
蠻力,屬性有:力量值
能量彈,屬性有:傷害值、射擊距離、同時射擊個數(shù)
我們創(chuàng)建了如下類:
class?Flight { ????protected?$speed; ????protected?$holdtime; ????public?function?__construct($speed,?$holdtime)?{} } class?Force { ????protected?$force; ????public?function?__construct($force)?{} } class?Shot { ????protected?$atk; ????protected?$range; ????protected?$limit; ????public?function?__construct($atk,?$range,?$limit)?{} }
好了,這下我們的超人有點“忙”了。在超人初始化的時候,我們會根據(jù)需要來實例化其擁有的超能力嗎,大致如下:
class?Superman { ????protected?$power; ????public?function?__construct() ????{ ????????$this->power?=?new?Fight(9,?100); ????????//?$this->power?=?new?Force(45); ????????//?$this->power?=?new?Shot(99,?50,?2); ????????/* ????????$this->power?=?array( ????????????new?Force(45), ????????????new?Shot(99,?50,?2) ????????); ????????*/ ????} }
我們需要自己手動的在構(gòu)造函數(shù)內(nèi)(或者其他方法里)實例化一系列需要的類,這樣并不好。可以想象,假如需求變更(不同的怪物橫行地球),需要更多的有針對性的?新的?超能力,或者需要?變更?超能力的方法,我們必須?重新改造?超人。換句話說就是,改變超能力的同時,我還得重新制造個超人。效率太低了!新超人還沒創(chuàng)造完成世界早已被毀滅。
這時,靈機一動的人想到:為什么不可以這樣呢?超人的能力可以被隨時更換,只需要添加或者更新一個芯片或者其他裝置啥的(想到鋼鐵俠沒)。這樣的話就不要整個重新來過了。
IoC?容器誕生的故事——青銅時代(工廠模式)
我們不應(yīng)該手動在?“超人”?類中固化了他的?“超能力”?初始化的行為,而轉(zhuǎn)由外部負責(zé),由外部創(chuàng)造超能力模組、裝置或者芯片等(我們后面統(tǒng)一稱為?“模組”),植入超人體內(nèi)的某一個接口,這個接口是一個既定的,只要這個?“模組”?滿足這個接口的裝置都可以被超人所利用,可以提升、增加超人的某一種能力。這種由外部負責(zé)其依賴需求的行為,我們可以稱其為?“控制反轉(zhuǎn)(IoC)”。
工廠模式,顧名思義,就是一個類所以依賴的外部事物的實例,都可以被一個或多個?“工廠”?創(chuàng)建的這樣一種開發(fā)模式,就是?“工廠模式”。
我們?yōu)榱私o超人制造超能力模組,我們創(chuàng)建了一個工廠,它可以制造各種各樣的模組,且僅需要通過一個方法:
class?SuperModuleFactory { ????public?function?makeModule($moduleName,?$options) ????{ ????????switch?($moduleName)?{ ????????????case?'Fight':?????return?new?Fight($options[0],?$options[1]); ????????????case?'Force':?????return?new?Force($options[0]); ????????????case?'Shot':?????return?new?Shot($options[0],?$options[1],?$options[2]); ????????} ????} }
這時候,超人?創(chuàng)建之初就可以使用這個工廠!
class?Superman { ????protected?$power; ????public?function?__construct() ????{ ????????//?初始化工廠 ????????$factory?=?new?SuperModuleFactory; ????????//?通過工廠提供的方法制造需要的模塊 ????????$this->power?=?$factory->makeModule('Fight',?[9,?100]); ????????//?$this->power?=?$factory->makeModule('Force',?[45]); ????????//?$this->power?=?$factory->makeModule('Shot',?[99,?50,?2]); ????????/* ????????$this->power?=?array( ????????????$factory->makeModule('Force',?[45]), ????????????$factory->makeModule('Shot',?[99,?50,?2]) ????????); ????????*/ ????} }
可以看得出,我們不再需要在超人初始化之初,去初始化許多第三方類,只需初始化一個工廠類,即可滿足需求。但這樣似乎和以前區(qū)別不大,只是沒有那么多?new?關(guān)鍵字。其實我們稍微改造一下這個類,你就明白,工廠類的真正意義和價值了。
class?Superman { ????protected?$power; ????public?function?__construct(array?$modules) ????{ ????????//?初始化工廠 ????????$factory?=?new?SuperModuleFactory; ????????//?通過工廠提供的方法制造需要的模塊 ????????foreach?($modules?as?$moduleName?=>?$moduleOptions)?{ ????????????$this->power[]?=?$factory->makeModule($moduleName,?$moduleOptions); ????????} ????} } //?創(chuàng)建超人 $superman?=?new?Superman([ ????'Fight'?=>?[9,?100], ????'Shot'?=>?[99,?50,?2] ????]);
現(xiàn)在修改的結(jié)果令人滿意。現(xiàn)在,“超人”?的創(chuàng)建不再依賴任何一個?“超能力”?的類,我們?nèi)缛粜薷牧嘶蛘咴黾恿诵碌某芰Γ恍枰槍π薷?SuperModuleFactory?即可。
【相關(guān)推薦:laravel視頻教程】