之前寫的 Cancan 實作角色權限設計的最佳實踐 和 OmniAuth - 實作多方認證的最佳實踐 系列剖析頗受好評。
社群朋友希望我再寫幾個常見但原理不是那麼好懂的 Gem,這次的主題是 cells。
Cells 的 Github 首頁的 description 是 View Components for Rails
。在 DHH 發明的 Caches Digest 推出前,它應該是開發者最常拿來處理 Partial Cache 的 Gem。
Model – View – Presenter (P.S. Don't do this)
在真正進入主題談 cells 時,我們先來談談 MVP 這個設計手法。MVP 是 Model – View – Presenter 的縮寫。
在一般實作 MVC 架構時,我們強調的是:
- 用於封裝與 「業務邏輯相關的資料」 以及 「對資料的處理方法」 必須放在 Model
- 至於 View ,只負責 「負責資料與介面的呈現」
不過,這是理想狀態。
專案中實際上會發生的狀況是:
- 網站 UI「高度依賴業務邏輯」
- 業務非常複雜,有時會逼得開發者不得不在 controller 或 view 中實作業務邏輯
- 雖然實務上會教我們將複雜的 method refactor 到 model 中。但現實狀況是:有些業務用 method 僅在該 View 使用一次。而且不屬於 Model 應有的基礎 method。什麼都往 model 扔的化,model 會變得異常肥大。
MVC 這樣的架構最後會不敷使用。最後會需要再實作一層 Presenter 封裝
- 將比較少使用,但又必須實作的複雜 / expensive 業務邏輯,抽出來放在 Presenter
- 一旦業務邏輯抽出來放在 Presenter,改動 UI 的難度就會變得比較低了
Cells ( View Components for Rails )
cells 的作者 Nick 曾經寫過一篇文章 Rails Misapprehensions: What the fuck is MVP? 抱怨過 MVP 這個設計手法在 Rails 並沒有解決「真正的問題」。而這也是他設計 cells 的動機。
Presenter 只處理了 complex view logic
的部分。
但我們真正在專案中會遇到的狀況是,專案裡
- View 裡面太多邏輯
- 因為 View 裡面太多邏輯,會有 Performance Issue。所以會進行 Cache。但 Cache 了以後很難寫測試..
- 根本沒辦法對這個 action 寫測試,因為太複雜了 ....
Cells 的想法是開發者並不需要強行在一層的 MVC 架構裡,在 Controller 把一次事情做完(撈資料,處理資料)。開發者可以使用 Cells 把這些複雜邏輯拆成一個一個獨立的邏輯元件(componet)去實作。而這些 component 是可以被複用、被 Cahce、可以被測試的。
簡而言之,在用 Cells 時,你是可以把 Cells 想成這樣的:
- 可以複用可以 Cache 的 Partial
- 這個可以被 Cache 的 Partial,自己有一個迷你的 Controller 和 View
在下一篇,我們會介紹 Cells 適用的場景與用法。