laravel的核心是服務容器,也就是IOC容器。該容器提供了整個框架中需要的一系列服務,其中包含了依賴注入和控制反轉兩部分,控制反轉是物件導向程式設計中的一種設計原則,可以用來減低計算機程式碼之間的耦合度。
本文操作環境:Windows10系統、Laravel6版、Dell G3電腦。
服務容器,也叫IOC容器,其實包含了依賴注入(DI)和控制反轉(IOC)兩部分,是laravel的真正核心。其他的各種功能模組比如 Route(路由)、Eloquent ORM(資料庫 ORM 元件)、Request and Response(請求和響應)等等等等,實際上都是與核心無關的類模組提供的,這些類從註冊到範例化,最終被你所使用,其實都是 laravel 的服務容器負責的。服務容器這個概念比較難解釋清楚,只能一步步從服務容器的產生歷史慢慢解釋
該容器提供了整個框架中需要的一系列服務。
IoC 容器誕生的故事——石器時代(原始模式)
我們把一個「超人」作為一個類,
class Superman {}
我們可以想象,一個超人誕生的時候肯定擁有至少一個超能力,這個超能力也可以抽象為一個物件,為這個物件定義一個描述他的類吧。一個超能力肯定有多種屬性、(操作)方法,這個盡情的想象,但是目前我們先大致定義一個只有屬性的「超能力」,至於能幹啥,我們以後再豐富:
class Power { /** * 能力值 */ protected $ability; /** * 能力範圍或距離 */ protected $range; public function __construct($ability, $range) { $this->ability = $ability; $this->range = $range; } }
這時候我們回過頭,修改一下之前的「超人」類,讓一個「超人」建立的時候被賦予一個超能力:
class Superman { protected $power; public function __construct() { $this->power = new Power(999, 100); } }
這樣的話,當我們建立一個「超人」範例的時候,同時也建立了一個「超能力」的範例,但是,我們看到了一點,「超人」和「超能力」之間不可避免的產生了一個依賴。
所謂「依賴」,就是「我若依賴你,少了你就沒有我」。
在一個貫徹物件導向程式設計的專案中,這樣的依賴隨處可見。少量的依賴並不會有太過直觀的影響,我們隨著這個例子逐漸鋪開,讓大家慢慢意識到,當依賴達到一個量級時,是怎樣一番噩夢般的體驗。當然,我也會自然而然的講述如何解決問題。
之前的例子中,超能力類範例化後是一個具體的超能力,但是我們知道,超人的超能力是多元化的,每種超能力的方法、屬性都有不小的差異,沒法通過一種類描述完全。我們現在進行修改,我們假設超人可以有以下多種超能力:
飛行,屬性有:飛行速度、持續飛行時間
蠻力,屬性有:力量值
能量彈,屬性有:傷害值、射擊距離、同時射擊個數
我們建立了如下類:
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) {} }
好了,這下我們的超人有點「忙」了。在超人初始化的時候,我們會根據需要來範例化其擁有的超能力嗎,大致如下:
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) ); */ } }
我們需要自己手動的在建構函式內(或者其他方法裡)範例化一系列需要的類,這樣並不好。可以想象,假如需求變更(不同的怪物橫行地球),需要更多的有針對性的 新的 超能力,或者需要 變更 超能力的方法,我們必須 重新改造 超人。換句話說就是,改變超能力的同時,我還得重新制造個超人。效率太低了!新超人還沒創造完成世界早已被毀滅。
這時,靈機一動的人想到:為什麼不可以這樣呢?超人的能力可以被隨時更換,只需要新增或者更新一個晶片或者其他裝置啥的(想到鋼鐵俠沒)。這樣的話就不要整個重新來過了。
IoC 容器誕生的故事——青銅時代(工廠模式)
我們不應該手動在 「超人」 類中固化了他的 「超能力」 初始化的行為,而轉由外部負責,由外部創造超能力模組、裝置或者晶片等(我們後面統一稱為 「模組」),植入超人體內的某一個介面,這個介面是一個既定的,只要這個 「模組」 滿足這個介面的裝置都可以被超人所利用,可以提升、增加超人的某一種能力。這種由外部負責其依賴需求的行為,我們可以稱其為 「控制反轉(IoC)」。
工廠模式,顧名思義,就是一個類所以依賴的外部事物的範例,都可以被一個或多個 「工廠」 建立的這樣一種開發模式,就是 「工廠模式」。
我們為了給超人制造超能力模組,我們建立了一個工廠,它可以製造各種各樣的模組,且僅需要通過一個方法:
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]); } } }
這時候,超人 建立之初就可以使用這個工廠!
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]) ); */ } }
可以看得出,我們不再需要在超人初始化之初,去初始化許多第三方類,只需初始化一個工廠類,即可滿足需求。但這樣似乎和以前區別不大,只是沒有那麼多 new 關鍵字。其實我們稍微改造一下這個類,你就明白,工廠類的真正意義和價值了。
class Superman { protected $power; public function __construct(array $modules) { // 初始化工廠 $factory = new SuperModuleFactory; // 通過工廠提供的方法制造需要的模組 foreach ($modules as $moduleName => $moduleOptions) { $this->power[] = $factory->makeModule($moduleName, $moduleOptions); } } } // 建立超人 $superman = new Superman([ 'Fight' => [9, 100], 'Shot' => [99, 50, 2] ]);
現在修改的結果令人滿意。現在,「超人」 的建立不再依賴任何一個 「超能力」 的類,我們如若修改了或者增加了新的超能力,只需要針對修改 SuperModuleFactory 即可。
【相關推薦:】
以上就是laravel的核心是什麼的詳細內容,更多請關注TW511.COM其它相關文章!