2.Rails應用程序的架構
Rail的有趣點之一是它對你的web應用程序架構實施了一些強制性規定。令人驚訝的是,這些規定反而能讓你很容易地創建應用程序-非常地容易。讓我們看看為什么?
2.1模型,視圖和控制器
追溯至1979年,Trygve Reenskaug 提出一種開發交付式應用程序的新架構。在他的設計中,應用程序被分為三種類型的組件:模型,視圖和控制器。
模型負責維護應用程序的狀態。有時候這種狀態的持續時間是短暫的,僅存在與用戶的交互過程中。但有時候這狀態又是持久的,它存儲在應用程序之外,經常是在數據庫。
一個模型通常不只是數據;它還執行了應用在數據上的規則。例如,若規定少于$20的訂單不予折扣,則模型將實行此規則。這是很有意義的。在模型中貫徹這些業務規則,我們能確保在應用程序中數據的有效性。 因而模型扮演著數據檢查及其數據存儲雙重角色。
視圖負責產生一個用戶界面,其通常是基于模型數據。例如,一個網上商店在分類中顯示一列商品。這些列表通過模型被訪問,但它是作為一個視圖(此視圖從模型中讀取列表)展示在終端用戶面前。雖然根據不同的輸入數據可以在用戶面前展示不同的視圖,但視圖本身無法改變這些數據,它要做的唯一工作就是顯示數據。為了達到不同目的,多個視圖也可能存取同一個模型數據。對在線書店,在分類頁面有個視圖用于顯示產品信息,同時也有若干視圖供管理員新增和編輯產品。
控制器從外部世界接收事件(通常是用戶的輸入),和模型進行交互,并給用戶顯示適當的視圖。
這三種,模型,視圖,和控制器――形成了大家熟悉的MVC架構。
MVC最初來源于傳統的GUI應用程序,在那里開發人員發現分離關注點可以減少耦合,而這反之又可以使代碼變得容易編寫和維護。每個概念和動作將在一個眾所周知的位置被表達。使用MVC就象建造已搭好鋼架的摩天大樓――只需進一步填充剩余零件。
在軟件開發世界中,我們經常在往前趕路時忽視了過去好的想法。當開發者第一次開始建造web應用程序,他們退回到寫集成電路程序了,在一個大的代碼塊中混雜著展現,數據存儲,業務邏輯,和事件處理。但是想法慢慢又回到了原來上了,人們開始把已經存在了20幾年的MVC思想應用在web應用程序的架構上。這樣的結果就出現了WebObject,struts和Java Server Faces 等框架。所有的這些都是基于MVC的思想上的。
Ruby on Rails也是一個MVC框架。Rails強調應用程序的模型,視圖和控制器之間的分離――在應用程序執行的時候把它們組織在一起。關于Rails有趣的是它把這些組織在一起是基于智能的默認設置而不需要你編寫任何的外部配置文件。這就是Rails哲學的一個例子,約定俗成優于配置。
在一個Rails應用程序中,接收到的請求首先被發送到一個路由器上,它用于決定在此應用程序中,請求將發送至哪里,及如何解析請求本身。最終,這個過程在控制器代碼中決定了一種相應方法(在Rails中通常稱為“動作”)。動作將根據請求查找數據,它可以和模型進行交互,并且它也可能導致其它的動作被執行。最后這個動作給視圖準備了信息,呈遞給用戶。
在下一頁的圖2.2上顯示了Rails是如何接收一個請求的。在這個例子中,假設在分類中顯示產品,用戶剛剛點擊了其中一個產品的“Add To Cart”按鈕。這個按鈕返回了一個http://my.url/store/add_to_cart/123鏈接給我們的應用程序,123是我們選擇的產品的內部編號。
路由器組件接收了請求并把它分為若干部分。在這個簡單的例子中,路徑(指的是/store/add_to_cart/123)的第一部分store作為控制器的名稱,第二部分add_to_cart作為動作的名稱,最后部分123,約定俗成為內部變量稱為編號。根據分析的結果,路由器在控制類StoreController中調用了add_to_cart方法。
add_to_cart()執行了用戶的請求。從而它查找到了當前用戶的購物車,并要求模型查找產品編號為123的信息,最終把產品添進購物車。
現在購物車里多了個新產品,我們要把它顯示給用戶看。控制器安排視圖從模型中取得了購物車的對象,并且調用視圖代碼。在Rails中,這個調用通常是隱含的。再次依據約定把視圖和已知動作連接起來。
以上所述就是一個MVC web應用程序。通過一些約定以及功能性的適當分割,你將發現你的代碼更易于操作,你的程序更易于擴展和維護。這看起來是一個良好開端。
如果MVC僅僅涉及如何通過一特定途徑分割你的代碼這個問題,你可能會質疑為什么還需要象Ruby on Rails這樣的框架。答案很簡單,Rails為你處理所有低級別的事務,包括所有冗長細節,使你能集中精力關注應用程序的核心功能。