almost 4 years ago

之前寫的 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 的難度就會變得比較低了
class Sites::ShowPresenter

  def hottest_topics
    @hottest_topics = @site.topics.hottest.limit(10)
  end

  def recent_topics
    @recent_topics = @site.topics.unhidden.recent(10)
  end

end
def show
  @presenter = Sites::ShowPresenter.new(@site)
  @headline_topic = @presenter.headline_topic
  @categories =  @presenter.categories
  @site_alias = @presenter.site_alias

  add_breadcrumb @site.name, site_path(@site)
  seo_meta_desc_keywords(@site)
end

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 適用的場景與用法。

系列連結:

← Logdown 付費會員限時半價 50% off Cells 實作 Partial 封裝的最佳實踐 (2) →
 
comments powered by Disqus