台灣最大程式設計社群網站
線上人數
1501
 
會員總數:244789
討論主題:188837
歡迎您免費加入會員
討論區列表 >> PHP >> 跟Codeigniter有關的IoC/DI, 來探討一些事
[]  
[我要回覆]
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
跟Codeigniter有關的IoC/DI, 來探討一些事
價值 : 0 QP  點閱數:838 回應數:0

樓主

皮皮快跑
中級專家
3387 23
5114 835
發送站內信

最近一直有人詢問關codeigniter的問題……
我想星空大也回應了不少。也講了不少觀念。
這邊我不是要探討ci的MVC架構,也不是要告訴各位CI怎麼去使用。
這邊要討論的東西偏向很進階。
但這是呼應星空大講的觀念:要去使用或改變一套東西前,你要具體了解他們的運作方式。
這邊接著的範例code其實和ci沒什麼關係但是可以應用在ci上面。
我想用過Laravel的人對以下這種載入物件實例的方式應該不陌生:


上面只是大略寫一下,我又有一陣子沒用Laravel所以有些忘了。
在路徑方面也許就會變成這樣:
http://xxx/dmeo/first_page/tkdmaf/taipei

嗯,於是就有人奇怪我面只有二個參數但是firstPage卻設置需求是三個參數……這乍看應該像是要error的東西。
當然在Laravel中他是不會出錯的。
理由是因為User的宣告表明$user是一個需要被載入的物件,所以他會被「注入」一個實體化的物件,而後續的param1和param2才是去接收網址列的參數。

這個機制很不同的在於……我們不需要去設置外部進入的物件參數,而是交由物件本身函式的參數來決定注入的對象。
跟依賴注入不同的是通常依賴注入是以不動程式碼本身,而是依照注入物件的功能的不同產生不同的結果變化。
但是這邊的做法並不是如此,而是在設計階段可以自行決定注入物件為何,以及設置不同注入物件的數量。
簡單來說他就沒有「依賴」……
這東西應該是屬於IoC「反轉控制」。
不去遵從外部給予的物件,而是從物件本身去要求載入的物件。
其實最基本的載入就只是在物件中new物件實體。
只不過麻煩事就是多一行……多一個new……還有設置名稱。(通常變數名會等同物件名就是了。除了把大寫變小寫)
但是這邊講這個東西其實有他必要的好處。
一般而言在ci我們載入model會使用$this->load->model('User','user');
於是我們就獲取了一個$this->user等於那個model的東西………
麻煩事在於每一個function都要來一次,如果你不想這樣可能你會考慮放在建構式。
於是我們就又遇到了一個問題:放在建構式結果沒用到就浪費掉了。

其實較新的php版本基本上已經有支援 spl_autoload_register()
有用過_autoload()的人都知道他的功能就是當物件不存在時會去找_autoload()來處理物件不存在的問題。
(通常就是不存在所以去做include進來的動作。)
這樣的好處當然就是有需要我才載入,沒需要就別進來。

這個功能拿來搭配反轉控制是很好用的。

如同上例需要載入User時才將User注入並直接指定給$user這個變數。
操作上相當的便利,而且也不用寫一堆$this->user而是直接用$user來當做model使用了。

舉一個我後來改變ci外掛的post + model的功能:

這個做法上來說就是分別有我寫好的Post和UserModel被載入
我寫的Post本身就已經處理ci的$this->input->post();
所以其實只要指定對像的model就可以直接進行新增。

當然我還設置像這種處理$post過濾的情形


這邊主要就是講如果將CI導入IoC的好處。
不過基本上……ci本身不具備這個功能。
是我寫的外掛讓他變成有這樣的功能。
而且即使到了ci 3.0仍然沒支援的namespace我相同的掛了上去。

不過………真的要完整去講我整個外掛大概講個一星期也講不完……導入太多的東西了。

但這邊要呼應的還是星空大說的……如果你對一個東西有所了解……你才有能力去改變他。
否則~~~~~~我覺得應該要先學會的是使用他。

因為時間很晚了。
下面我直接附上跟Ioc有關的一段範例code。
原則上class應該是要分檔的但因為我重組文件時間有限暫時全放在同一隻。
我會建議大家可以實際跑跑看內容。
程式碼本身不多。
但好好理解一下這樣的設計會帶來什麼不同的設計思維和方向。

ci的改版外掛計劃我目前依然持續進行中。
也把一些不好的設計再修正。什麼時候會釋出我現在還沒個底。
因為雖然在controller、model跟library大致方向是底定了。
但是view的問題還是一直困擾著我……到底該怎麼設計比較好。

我附上的code跟我的改版內容有絕對的關係……但實際改版的內容還比這個要複雜很多。
套用不少觀念………

以下的code比較需要注意的是……MyClass相當於我上面的Post,也就是要被載入使用的類別。
而Demo其實就是平常我們寫ci的controller
Module...有玩過以前ci的hmvc的人應該不陌生。只是我這邊只是名稱相同,內容則略有不同。
然而要修改ci的一些核心行為跟這樣的動作有關係就是了。
(事實上……ci外掛改進計劃中我堅持的一點就是不動核心………不過唯一例外的就是index.php去載的Codeigniter.php因為有酪地方
實在不改不行所以我讓他去載「改過」的檔案,基本原位置的檔案還是沒動就是了。)




最後還是呼應星空大講的……
要改或是要提出功能……一定要對該系統有具體的了解,甚至要理解底層實現的模式你才有改變他的能力。

即使是我……在這個改版計劃中還是有遭遇到一些難題。
不斷的修正改變他的觀念才得以持續下去。
如果沒辦法做到這一點……不要去想著要去抽取或是改變些什麼………
雖然ci外掛改版計劃在我手上變成大改計劃了………連routers都被我改得相當嚴格就是了。
沒在routers設定的路徑就一定無法執行。

以上………我知道這內容已經有些難以理解了………不過嘗試理解的話會相當有趣就是了。

搜尋相關Tags的文章: [ IoC ] , [ IoC/DI ] , [ CodeIgniter ] , [ codeigniter ] , [ 控制反轉,依賴注入,php ] ,
本篇文章發表於2015-12-14 02:25
== 簽名檔 ==
發問的美學:
1.確定你的先備知識條件足夠,基礎該學習的就不應該問人。
2.先思考過或先google過。
3.明確表達問題。
4.表達明確,能詳細問題的code。
5.發問的問題,絕不刪除,留給其他遇到相同問題的人一個好的紀錄。
6.我的skypelinetkdmaf,歡迎直接詢問。
別忘捐VP感謝幫助你的人 新手會員瞧一瞧
目前尚無任何回覆
   

回覆
如要回應,請先登入.