利用 MVP 與 Cells 整理你的程式碼

标签: Rails | 发表时间:2011-08-28 00:34 | 作者:xdite chitsaou
出处:http://blog.xdite.net

在這次的 rubyconf 中,我在整理程式碼的技巧中,介紹了兩節比較少人使用的技巧:MVPCells

MVP ? 聽起來怎麼跟 MVC 好像?他們有什麼關聯嗎?

沒錯,MVP 其實就是 Model – View – Presenter 的縮寫。

什麼是 MVP

在一般實作 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

這樣就能大幅提高 code 的維護性。

什麼是 Cells?

即便如此,Presenter 還是不夠用的。

這也是 Nick 寫下 Rails Misapprehensions: What the fuck is MVP? 一文的主要原因。

( 演講會後,我有跟作者 Nick 小聊了一下。稱讚了他的 Cells 設計。他感到很爽,覺得終於有人懂他設計 Cells 的原因了。並感到奇怪,明明他的文章寫的很清楚了,為什麼一堆人還是搞不懂?Cells 還是很少人用。要我報個 LT 延長篇幅幫他廣告一下 XD)

不夠用的原因,是在於 Presenter 只做到了整理 Controller 的動作。MVP 只是把「大段的程式碼」搬離 Controller。

並沒有解決真正需要解決的原因:

「無可避免的在 Views 裡面實作邏輯,query 資料」

也許你會想,What’s the big deal ?

Big deal

我會開始使用 Cells,初衷並不是因為想嚴謹的遵循 MVC。而是因為需要 Cache 的 code 越來越多,我需要一個比較好的方式去整理現在專案裡需要被 cache 的 Code。

Cells 整理 code 的方式很符合我的需要,於是我們開始將大段的程式碼搬到 Cell 去做 cache。

一個月後,又到了我例行整理 Bad performance code 的時間。

專案中一些程式碼其實很討厭,你不免的必須在 View 中跑迴圈 query 資料,比如這樣的 code :


  <% sites.each do |site| %>
    <% site.categories.each do |category| %>
      <% category.popular_posts.each do |post| %>
         <%= post.title %>
         <%= post.content %>
      <% end %>
    <% end %>
  <% end %>

這種 code 非常非常的痛。Developer 幾乎對這種 code 一點辦法都沒有。

因為你能做的只剩下

  • 整片打 cache,在背景 preheat cache
  • 拆成 partial 逐層打 cache。在背景preheat cache
  • 在 controller / presenter 裡下 includes 變成 join 減少 query 數量。

OK。讓我告訴你,這其實都沒什麼用,因為速度快不了多少。

這只是把 performance issue 拖到後面去解決而已。

速度緩慢的真正元兇

真正速度緩慢的元兇是:Query in View 。

Rails Developer 都知道,partial 很慢。但很少人去究其因,只把問題怪在 Rails 上。

但其實如果你認真的去追,會發現放純 html 的 view,其實 render 的非常快。

真正慢的都是那些被迫必須在 View 裡面 處理資料 / query 資料的 partial。

ULTRA SLOW

隨隨便便在裡面 query 一個東西。整個 partial 就慢得要死。

更糟糕的是,如果你的 Header 選單是需要 Query 資料的,恭喜你!中大獎!

怎麼解呢?

搬到 Controller 去 query 囉!

但是上一段這種 code,根本就搬不動啊 …

Cells 提供的解決方法

Cells 的運作原理是將每一段需要 cache 的 code,化做一段 component。而這個 component 有自己的 "mini controller" 與 "view"。

藉由 Cells 的機制,我們可以大幅的將 heavy query 拆到 mini-controller 去,而非在 view 裡面實現。

這不僅解了程式潔癖者的癮( 沒有照 MVC 放 code ),其實更解決了嚴重的 performance issue。

就像上一段的 code,其實我可以將之拆成三層 cell。

使用這樣的技巧,我成功的使用 Cell 重寫了一段骯髒的程式碼。而運行的時間從 550ms 大幅降到 10ms。(不管你信不信,我反正是信了)

Cells 背後的故事

當我想通 Cells 背後的道理其實是解了雙重的 issue ( MVC 與 query in view’s performance issue )之後,不禁打從內心讚嘆這樣厲害的設計。興奮了好幾天。

這次 Rubyconf,我就特別跑去問作者 Nick 是不是這樣的想法,他相當開心遇到一個知音,並跟我抱怨一堆人都不用 Cells,讓他很鬱卒…明明他把 Cells 和 Presenter 的說明寫的很簡單,還是一堆人看不懂 ..

接著就拿出他老早寫好的投影片,強迫我和我們家的 SA vincent 去幫他 LT XDDDDD

之後我問他,怎麼想出來這樣的 Idea。他說:「我用了 Ruby 兩小時,再用了 Rails 兩個小時,然後就受不了這麼愚蠢的 MVC,自己幹了一套……」 # XDDDDD

結語

如果你有 Performance 上的 issue,先別怪罪 Rails,先看看你的 partial 是不是採取這樣的設計吧。Cells 不只是一個整理 cache 的好工具,其實更是整理 Code 的一個絕佳工具。幫助你的 code 更 MVC,跑起來更高效。

廣告: Essential Rails Design Pattern for Beginners 一書,即日起開放預購。原價 14.99 USD 。預購只要 9.99。本書將在九月底或十月初出版。

本章「利用 MVP 與 Cells 整理你的程式碼」也將收錄在此書中。

相关 [利用 mvp cells] 推荐:

利用 MVP 與 Cells 整理你的程式碼

- chitsaou - Blog.XDite.net
在這次的 rubyconf 中,我在整理程式碼的技巧中,介紹了兩節比較少人使用的技巧:MVP 與 Cells. 沒錯,MVP 其實就是 Model – View – Presenter 的縮寫. 在一般實作 MVC 架構時,我們強調的是. 用於封裝與 「業務邏輯相關的資料」 以及 「對資料的處理方法」 必須放在 Model.

2011 品牌 MVP :Google

- wind - 谷奥——探寻谷歌的奥秘
BrandFinance® 公布了他们的年度报告,并将年度最有价值品牌奖颁给了 Google. 微软从去年的第五名升到了第二名,而去年冠军 Walmart 则落到了第三. Apple 则从第二十名火箭般窜升至第八. BrandFinance® 称:. 正因为这个世界越来越依赖互联网,所以才会将 Google 推向第一名的位置.

[Architecture] MVP, MVC, MVVM, 傻傻分不清楚~

- Amo - 點部落-小朱® 的技術隨手寫

MVP(最小可行产品)的重要含义

- - 明学的白板
SILY系列文章第52期:MVP 必须向用户提供价值,换句话说,也就是验证问题是否真的存在,解决方案是否真的带来了改善. 精益创业中强调要使用 MVP 来验证问题确实存在,而 MVP 其实是最多被误解的一个定义. MVP 和 高保真原型的区别是什么. @jopas,画了一张非常棒的图表,让 MVP 的概念瞬间清晰:.

Android中的MVP架构分解和实现

- - IT瘾-geek
传统的Android开发架构一般是MVC模式,. Model:业务逻辑和实体模型. View:对应于布局文件. Controllor:对应于Activity. 单独从逻辑看起来非常好,与我们做Web开发时,开发模式类似,但在实际开发中,View对应于布局文件,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,Activity既像View又像Controller(MVVP架构中包括数据绑定),导致Activity中职责太重,耦合度大.

利用sockstunnel翻越

- - 0.618網絡空間
首先在你的linux vps上搭建python環境(一般來說,linux vps都已搭好了python 環境). 然後運行如下命令(假設你在/root下):. 這樣在/root/下,就生成了privkey.pem和cacert.pem. 修改sslserver.py裏的. keyfile="privkey.pem",為.

转角的空间利用

- Ivy - IDSOO
拐角的空间如果不充分利用似乎有一些浪费. 日本的设计工作室Torafu Architects设计的这个隔板巧妙地利用了拐角,搭建了一个可以放置物品的平台,设计实用、美观、大方.

旧灯泡的再利用

- Jimmy - 微奇生活
生活水平提高了,家家户户也用上了节能灯,那些废旧的白炽灯泡如何利用呢. 看看下面这些妙点子吧,可以种盆栽,做工艺品,还能用来养金鱼~~灯泡还会跳舞呢. 简洁的线圈灯:Coil Lamp. 微博:@新浪 | @腾讯     订阅:Google | 九点 | QQ | 鲜果 | 有道 | 邮箱.

[译]jboss漏洞利用

- - 互联网 - ITeye博客
原文地址:http://resources.infosecinstitute.com/jboss-exploitation/. JBoss Application Server是一个基于Jave EE的web应用服务器. 如果Jboss没有正确配置,它会允许攻击者进行各种恶意攻击. 由于JMX console可以通过端口8080远程访问,攻击者和恶意用户可以通过使用Jboss console中的DeploymentScanner功能部署他们自己的WAR(web archive)文件或shell脚本.

利用HTTP Cache来优化网站

- scourgen - 博客园-首页原创精华区
对于网站来说,速度是第一位的. 用户总是讨厌等待,面对加载的Video和页面,是非常糟糕的用户体验. 所以如何利用Cache来优化网站,值得深入研究. 缓存是一个到处都存在的用空间换时间的例子. 通过使用多余的空间,我们能够获取更快的速度. 用户在浏览网站的时候,浏览器能够在本地保存网站中的图片或者其他文件的副本,这样用户再次访问该网站的时候,浏览器就不用再下载全部的文件,减少了下载量意味着提高了页面加载的速度.