而我發此文的目的有二:一者,讓初學者能夠聽到一家之言,是為解惑;二者,更希望拋磚引玉,得到專家的批判。
許多學生經常問我,MVC到底和WEB三層架構有啥關系? 開始時,我也只能給他們一些模糊的回答。時間長了,自己的良心開始受到譴責。對於一個程序員來說,這個問題顯得挺學究。我在跟自己的許多程序員朋友以及同 行(Java講師)都對MVC和WEB三層架構的關系做了探討。現在可以說對WEB三層架構和MVC之間的關系理出了頭緒。此可謂教學相長。
先說說Web三層架構這個古老話題。地球人都知道web三層架構是指:
- >用戶接口層(UI Layer)
- >業務邏輯層(Bussiness Layer)
- >持久化層
關於業務邏輯和用戶接口
在早期的web開發中,因為業務比較簡單,並沒有這三層的划分。用戶數據的呈現及輸入的接收、封裝、驗證、處理、以及對數據庫的操作,都放在jsp 頁面中。這時的開發,好比盤古尚未開天辟地,整個web開發就是一片“混沌”。隨着業務越來越復雜,人們開始考慮更好的利用OOP這把利刃來解決問題。於 是有人發現把業務邏輯抽取出來並形成與顯示和持久化無關的一層,能夠讓業務邏輯清晰,產品更便於維護。這就是SUN當初倡導的JSP Model 1開發方式。
關於持久化
JSP M1開發方式中,並沒有對數據如何持久化給出建議。在許多公司中,它們的產品是以數據庫為中心進行架構和設計的。在他們的產品里,雖然也有DAO層,但是 職責不清。為什么這么說呢,因為我發現在許多人眼里,DAO層的指責很簡單——增刪改查。但我認為,這樣理解實際上是本末倒置了。對於簡單數據的管理來 說,這樣理解無可厚非。但隨着業務邏輯變得日益復雜。我們實在是被復雜的對象關系搞頭疼了,如果這時我們還要考慮如何把數據存儲起來(通常的情況下是存到 關系型數據庫中),我們開始抱怨自己軟件的架構太惡心,一團糟。面向對象設計思想教會我們——如果我們不想做這件事,就交給別人做吧!這時聰明的架構師們 提出了一個概念——持久化。如果我們在自己的應用中添加一個新的層——專門負責對象狀態的持久化保存及同步,那不就可以全心全意的“搞對象”了嗎?持久化 概念的產生,代表着我們對關系型數據庫的依賴降低了。因此甚至有人推斷——數據庫已死。同時,關系型數據庫這個新的概念也不斷形成,並演化成理論,又由理 論衍生出產品。因此一個意識良好的程序員,至少應該認同,持久化並不是產品中最重要的環節——最重要的環節是清晰正確的業務邏輯。
灰色地帶
是的,從理論上看,web三層架構很美了。但在實際開發產品的時候,我們發現了很多問題。主要問題就是用UI層和業務層之間有許多灰色地帶。這些灰色地帶業務邏輯層不想管,UI層也不想管。讓我們舉一些例子:
例子1, 難以管理的頁面跳轉關系
上圖是我在講JSP課程時,一個簡單案例的頁面跳轉關系圖。這是一個十分簡單的例子,但頁面跳轉關系已經挺復雜了。試想,如果你正在做一個有上百張 表,十幾個核心模塊,幾百個頁面的產品時,這張圖將變得多么復雜!而問題是,這些頁面跳轉關系分散在JSP和Servlet中,非常難以管理。
例子2,表單數據的驗證及封裝:
假設我們正在做一個簡單的表單提交,我們希望對用戶數據的數據進行驗證和封裝,最終交給業務邏輯層一個實體對象。從三層架構分析,我們想要做的事情是這樣的:
但是該把驗證和封裝數據的工作交給誰來做呢?UI層還是業務邏輯層?都不太合適!
例子3,國際化:
如果我們想為不同國家和地區的人提供不同的語言,無疑需要國際化的支持。那么,我們需要在JSP頁面上根據用戶的配置或請求信息判斷應該為該用戶呈現哪國文字。而這些判斷和顯示的邏輯應該划分到業務邏輯層還是UI層呢?
用MVC的思路解決問題
對於糾纏不清的問題,我們總要想辦法將其分解。MVC是一種設計思想。這種思想強調實現模型(Model)、視圖(View)和控制器的分離。這種思想是如何作用於web的呢?實際上,我們在web開發中引入MVC思想,想要達到的目的是: 實現UI層和業務邏輯層分離——控制器是為了實現上述目的而存在的!
在解決了持久化的問題后,我們發現,我們的所說的業務邏輯層和MVC中的Model指的是一回事,我們所說的UI層和MVC中的View是一回事。 MVC提供了讓模型和視圖相分離的思路——引入控制器。我們把頁面跳轉關系管理、表單數據的封裝及驗證、國際化等任務交給控制器處理。因此,也不難理解為 什么流行的MVC框架都具有管理頁面跳轉關系、表單數據的封裝及驗證、國際化等特性。
總結
在Java web開發中,MVC框架充當了UI層和業務邏輯層的適配器的作用。MVC框架實現了UI層和業務邏輯層最大程度的分離。