Laravel 對中大型專案的架構設計
初學laravel時分兩種 一種是乖乖的將程式填入MVC架構中 導致controller 和 model異常的臃腫 controller對model高度依賴導致專案在壯大時難以維護. 另一種是不知道程式該寫在哪一個class內 畢竟傳統 php都是一頁一個程式.這裡整理出最適合laravel的大型架構,兼具易維護 易擴充 容易重複使用的特點。
受RoR的影響,傳統的認為 MVC 就是 model
, view
, controller
:
- Model 就是資料資料庫。
- Controller負責呼叫 model 和view。
- View 就是 HTML。
假如按照傳統的MVC概念 那麼如下的需求應該怎麼寫呢?
- 傳送 簡訊驗證碼,使用外部 API。
- 使用php呼叫api完成業務邏輯。
- 依照需求將格式顯示。
- 依需求是進行對轉換的格式進行內容篩選。
- 依需求顯示不同資料。
其中 1, 2屬於業務邏輯,而 3, 4, 5 屬於顯示邏輯,若依照一般對 MVC 的定義,model 是資料資料庫,而 view 又是 HTML,以上這些需求都不能寫在 model 和 view,只能勉強寫在 controller。
因此將大量程式寫在 controller,造成 controller 的臃腫和難以維護。
Model 過於臃腫
既然邏輯寫在 controller 不方便維護,那我將邏輯都寫在 model 就好了?
當你將邏輯從 controller 搬到 model 後,雖然 controller 變瘦了,但 model卻臃腫,model從原本代表資料庫,現在變成還要負責業務邏輯和顯示邏輯,結果更慘。
Model 代表資料資料庫嗎嗎?把它想成是 Eloquent class
就好,資料庫應該在 repository 裡,這也是為什麼 Laravel 5 已沒有 models目錄
,Eloquent class 僅僅是放在 app
根目錄下而已。
中大型專案架構
那我們該怎麼寫呢?別將我們的思維侷限在 MVC 內 :
- Model :僅僅是一個Eloquent class。
- Repository
- Service : 輔助 controller,處理業務邏輯,然後注入到 controller。
- Controller : 接收 HTTP request,呼叫其他 service。
- Presenter : 處理顯示,然後注入到 view。
- View : 使用 blade 將資料 繫結到 HTML。
通過上圖我們發現 MVC架構其實還在 由於SOLID的單一職責與 依賴反轉原則
- 我們將資料從model 分離出來,由 repository 輔助 model,將 model 依賴注入進 repository。
- 我們將業務邏輯從 controller 分離出來,由 service 輔助 controller,將 service 依賴注入進 controller。
- 我們將顯示邏輯 view 分離出來,由 presenter 輔助 view,將 presenter 依賴注入進 view。
單元測試
由於現在將 model、view、controller 的相依物件都已經拆開,也都使用依賴,因此每個部分都可以單獨的做單元測試,如要測試 service,就將 repository 加以 mock,也可以將其他 service 加以 mock。
Presenter 也可以單獨的進行單元測試,將其他 service 加以 mock。
Conclusion
- 本文談到的架構只是開始,你可以依照實際需求增加更多的目錄和class,當你發現違法 SOLID原則,就大膽的將 class 從MVC拆開重構