三層架構和 MVC 那點事兒
前言: 這是個老生常談的話題了, 但我估計很多人還是會有疑惑, 我把自己的思考和大家分享下, 歡迎批評指正。
據說在上個世紀40年代, 有個叫IBM的公司宣稱, 全世界只需要5臺計算機就夠了!
當時的人們肯定預料不到未來蓬勃發展的PC, 更想不到人們對計算有著多么大的需求。
那時候電腦是一個稱為 啞終端 的東西, 這個東西可憐到只能用來發送、接收和顯示字符, 不能安裝程序, 沒有復雜的交互, 即使是這樣, 還只能是少數人有機會去使用。
但是,這個啞終端和一個無所不能的龐然大物相連接, 叫做“mainframe”, 這個怪獸掌管著所有的程序和數據。 這些啞終端就像是這個怪獸的觸角而已, 離開了母體, 幾乎沒什么用處。
歷史車輪滾滾向前, 從上世紀80年代開始, 個人計算機開始迅速的進入千家萬戶。
這些叫做PC的東西具備不錯的計算能力,存儲能力和顯示能力, 完全不需要那個大怪獸就可以生存。
再加上局域網蓬勃發展, 大家馬上想到, 能不能把Mainframe的部分功能移到PC上來?
這樣既可以充分的利用資源, 又可以把Mainframe給弱化, 也許只用一個普通的服務器就能干活了。
想來想去, 數據庫還是不能動, 還得要一個服務器來支持。
但是這業務邏輯,界面處理是不是可以放到客戶端PC中來了? 于是就出了這么一個結構:
客戶端的應用程序可不僅僅是顯示字符了,它承擔的任務很重, 要負責界面接口(我們常說的表示層邏輯), 業務邏輯, 還要負責和數據庫服務器的通信, 有個很形象的詞來稱呼這些客戶端應用程序: 胖客戶端(fat client) 。
這就是典型的兩層(2-tier)架構, 在90年代風靡一時, VB, PowerBuilder, Delphi可以說是其中的代表, 這些工具都具備快速開發的能力, 通過拖拽控件到表單上, 很容易形成界面, 然后把控件和數據庫的數據綁定就可以了。
客戶端“變胖”是個進步,計算開始分布, 資源可以平衡, 但是這個架構也有幾個缺點。
首先是每個客戶端需要直接一個數據庫連接, 發出查詢, 顯示數據。 由于客戶端直接連接數據庫,而數據庫的連接又是非常寶貴的資源, 無法支持大量的客戶端來訪問,所以2-tier架構是用在局域當中的, 很難想象數據庫暴露給海量的互聯網用戶直接訪問。
其次業務邏輯和表示層邏輯綁在一起, 一旦業務邏輯有修改, 就意味著客戶端的整個應用程序都要改一遍, 哪怕是修改了一點點業務邏輯, 那怕是這點邏輯對界面沒有任何影響, 對不起, 請您重新發布, 測試,部署到所有的客戶端吧。
所以把業務邏輯層和表示層分離開, 讓各個部分各司其職,盡量獨立,減少依賴成為了下一步的目標。
隨著互聯網的興起, 尤其是應用服務器和中間件的出現, 業務邏輯找到了容身之所, 成功的和表示層邏輯分了家, 2-tier 迅速被 3-tier 架構所替代。
客戶端的應用程序減肥成功, 只負責表示層邏輯(界面接口), 可以是一個獨立的應用程序, 也可以是Web頁面, 后者更加流行, 因為一個瀏覽器就可以工作了, 打開即用, 都不用安裝。
那些不講邏輯的業務邏輯被移到了服務器端, 可以盡情的修改, 只要不影響接口就行。
凡事都有利有弊, 分層要求某一層只能和自己的鄰居打交道,不能跨層訪問。
例如表示層不能繞過業務邏輯層直接訪問數據庫, 非得通過業務邏輯層不可。 數據在各層之間傳來傳去, 效率肯定有損失。
級聯的修改也不可避免, 做過Web開發的應該深有體會, 客戶說我們要在界面上加個新字段啊, 程序員把表示層改了當然不夠, 業務層需要改, 數據庫也得聯動。
注意, 我之前提到層的時候,用的詞都是 Tier , 而不是 Layer 。
雖然這兩者經常互換使用, 但是確實有差別, 據Wikipedia定義, Tier 一般指的是物理的結構, layer 指的是邏輯結構, 舉個例子, 一個3-layer的解決方案可以部署到一個tier上例如一個服務器。
現在我們把視線轉向邏輯結構, 拋棄那些PC, 應用服務器, 數據庫服務器 , 把3-tier 變成 3-layer 。
注意:從現在開始, 我們提到的層都是layer 了。
你看業務層和數據訪問層是不是可以放到一個物理的服務器上的, 實際上我們也是這么做的:例如 Spring 可以認為是個業務層框架, Hibernate是個數據訪問層的框架, 它們倆完全可以部署到一個應用服務器中(如Tomcat), 沒有任何問題。
可能有人要問了, 我鐘愛的Struts/Spring MVC 在哪兒? 這些MVC的實現框架實際上應該屬于表示層, 至少是說C(Controller)和V(View)屬于表示層:
當然這是一個非常簡化的圖, 現實會復雜的多的多, 例如:
1. 像Struts 有一個前端控制器(Front End Controller), 會把請求分發給一個個具體的Action 來處理。
2. 無論是Controller 還是Action, 通常不會直接訪問Model, 而是訪問一個叫做Service層的封裝, 其中可以處理安全和事務。
3. View 通常不會直接訪問Model , 也會封裝一下 , 例如通過Helper類, ViewBean等等
......
可以看出,這些MVC框架實際上都是放在服務器端的, 它接收HTTP請求, 輸出HTML+Javascript+CSS 到客戶端機器, 在瀏覽器中運行起來 。
這里說的還是相對“傳統”的架構, 現在新的趨勢又開始形成, 那就是前后端分離, 服務器只剩下了業務層, 用于執行業務邏輯和提供接口, 表示層完全被移到了瀏覽器當中,那就是另外一個故事了。
來自:http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513406&idx=1&sn=377d8a38a3f1c941addb3482a8c1f25d&chksm=80d679fdb7a1f0ebd837c49d68f5070cd3093f84a0233ba49c38c27cdbde805360ee2b67f627#rd