從三層架構到MVC,MVP

本來是不想跳出來充大頭蒜的,但最近發現園子裏關於MVC的文章和討論之風越刮越烈,其中有
些朋友的觀點並不是我所欣賞和推薦的,同時最近也在忙着給公司裏的同事做MVC方面的“掃盲工作”。
所以就蒐集了一些大家接觸MVC的過程中經常出現的問題做了一下解釋說明,希望能與大家多多交流,
呵呵。

     當然這種架構模式本身的一些問題也會在接下來的內容就加以介紹,另外就是如果大家有什麼
不同觀點的話,歡迎拍磚(只要不打臉就行,呵呵)。

    一.  MVC是誰提出的    
     模型-視圖-控制器(MVC)是Xerox PARC在八十年代爲編程語言Smalltalk-80發明的一種軟件
設計模式,至今已被廣泛使用。最近幾年被推薦爲Sun公司J2EE平臺的設計模式,並且受到越來越多的
使用 ColdFusion 和 PHP 的開發者的歡迎。模型-視圖-控制器模式是一個有用的工具箱,它有很多
好處,但也有一些缺點。

    二.  MVC是否適合進行大項目的開發
    MVC框架肯定是適合於做大項目開發的,但並不是說有了MVC框架我們就可以開發大項目,聽起來
有些繞,其實道理很簡單,原因就是人(開發者)。如果你是一個對MVC框架的設計理念有深入研究
的人,那麼你在使用MVC框架進行產品和項目開發的時候就會隨時隨地都要考慮一些問題:

    1.低耦合性(強調視圖層和業務層分離)
    2.可測試性(這個非常重要)
    3.高重用性和可適用性
    4.有利於軟件工程化管理等等。

    這裏我很欣賞老趙的治學態度,因爲在他的文章和代碼中隨時隨地都在進行着思考,特別是其對
可測試性,單元測試(這裏不是什麼TDD)的思考,讓我看起來有心靈相通的感覺。因爲這些問題都
是在做中型甚至大型項目中要認真思考的,決不是說微軟給的例子就是我們的唯一準則,必定裏面有
對也有錯,我相信在MVC面前,國內甚至微軟內部的牛人都不是很多。

    說了這些,大家可以意識到了,如果在沒有理解下面這張圖以及對MVC的“所謂優點是從何處得
到的”有認識,而一上來就去拿MVC去開發大型項目的話,我想不僅不能發揮asp.net MVC框架的估
勢,相反會時時受制於裏面的約束,配置和功能特性,最後感覺還不如直接用asp.net webform開發
來的直接,不是嗎?真要是到了這一境地,我想不僅無法使用MVC進行大型目開發,就連中小企業應
用都應付不來。

         

   

     三.  能不能使用MVC架構進行Webform的開發    
     在園子裏有人嘗試使用ASP.NET MVC 框架來進行webform方式的開發,我個人是不欣賞這種做法
的,這就好比在使用LINQ的項目中又同時使用SQL語句一樣“怪異”,這在代碼的整體風格上會讓人
產生迷惑,不是嗎?當然老趙也在他的視頻課程中提到在webform頁面中使用一些MVC功能(比如:
ModelBinder等),但我想老趙的本意決不是讓這種混合方式的開發大行其道,必定這是“非主流”,
所以孰輕孰重還是要大家自己把握的。
   

     四. 傳統的三(N)層架構與MVC,以及MVC與MVP關係    
     本文所說的三層架構指:表現層(顯示層), 業務邏輯層, 數據訪問層(持久化)。如果大家
非要“生搬硬套”的把它與MVC扯上關係的話,那我就只能在這裏"強扭這個瓜"了,即:

     三層架構中"表現層"的aspx頁面對應MVC中的View(繼承的類不一樣)
    
     三層架構中"表現層"的aspx.cs頁面(類)對應MVC中的Controller,理解這一點並不難,大家想一想
我們以前寫過的Redirect,當然它本身就是跳轉了一些鏈接頁面,而MVC中的Controller要做的更爽,
它控制並顯示輸出了一個視圖。即然所起到的作用都是對業務流程和顯示信息的控制,只不過是實現
手段不同而已。

      三層架構中業務邏輯層和數據訪問層對應MVC中的Model(必定View和Controller已找到“婆家”,
剩下的Model只能是業務業務層和數據訪問層的了,呵呵)。但其實微軟的一些MVC示例項目中對這個
問題理解的並不是這樣簡單,這一點在我之前的
關於兩個MVC示例的思考(MVCStore和Oxite) 已闡述
過,就不多說了。  
    
     其實明白了這個關係,就可以嘗試把以前的三層結構遷移到MVC框架下,當然在這個過程中肯定
會遇到這樣或那樣的問題,但原則就是把將MVC的優勢發揮到極致,要不然還不如不做。

     說到這裏,其實早在N年前就有人提出使用FrontController(前端控制器)來實現對HTTP頁面請
求的路由跳轉(包括數據的展現),說白了就是使用HttpHandler來進行頁面請求的處理和數據綁定,
而不是完全“指望”普通的頁面訪問重定向等。這樣做的目的,就我而言與Routing中的Controller
和Action的出發點標是一致的,只不過Routing實現的更優雅同時也更底層一些。

     說完了三層架構,再看看MVC與MVP,其實在這之前我們有必要看一下這張圖:

 
         
     看完了上面的圖,大家就會發現MVP與MVC最大的一個區別就是“Model與View層之間倒底該不該
通信(甚至雙向通信,如圖)。我想這也是目前做這兩方面研究的專家所互相爭論的戰場。必定各
有各的好處和因好處要付出的代價。起碼在MVP模式下的Presenter要擁有“絕對權力”。如果沒有它,
MODEL與View就是兩個孤島,儘管各有各的地盤(完全解耦),但不會給企業帶來什麼有用的價值。
所以我這裏有一個比喻來形容MVP中的:

     Presenter ----就是一個控制慾極強的女人,甚至就連“用什麼姿勢”,它都要管一管。
    
     當然日裏萬機操心多了就會讓自己要做的事越來越多,最終它面臨的就是該層代碼日益龐雜,
且書寫起來不太方便,必定就連事件綁定這類雞毛算皮的事都要歸它管,累不累呀。最終我們看到
MVP中的View就真的代碼輕閒了不少(國企職工嘛),難怪說View只要從相應的IVIEW接口下實現相
應的屬性和一些簡單方法就完事了,而最終調用IVIEW接口下的那個視圖實例則完全交給了Presenter,
這讓我想到了MVC中可以支持“自定義模版引擎(最終由MVC框架來控制使用系統還是自定義的模版
引擎)”以及平時大家常掛在嘴邊的換膚功能,想到這裏多少還真有那麼點意思了(精神層面上)。

     當然在微軟內部對MVP的理解也有所不同,如下圖中所說的Supervising Controller模式和上面
大家看到的PassiveView.
 

     Supervising Controller模式其實很接近於MVC的那張圖了,只是又提供了Presenter與View之間
的“雙向通信”。這種做法也是有很多不同意見的,起碼對那些支持“單向依賴”的開發者而言是“
嗤之以鼻”的。

     說到這裏,表達一下我的觀點,我是偏向於PassiveView的,雖然這種模式有些霸道,但必定是
讓Model和View之間真正解耦,爲開發者提供了最大的“控制成就感”,可以說想怎麼控制視圖就怎
麼控制,但因此所造成的問題就是代碼書寫量和實現複雜性等問題了。

      

     五.  Controller和Model中該有哪些東東    
     因爲VIEW中的邏輯比較簡單,所以對系統複雜性的考慮基本上要重點放在Model中,而Controller
是對業務流程的控制,其應該保持“代碼清爽”。說是這麼說,但實際進行項目開發時這兩者之間的
界線能這麼清楚嗎,答案是“儘量保(堅)持”。必定這是MVC的“特色”嘛。

     另外這裏向大家推薦一個不錯的方法"Robustness",有了它您就可以很容易的找出那些系統方法
要放在MODEL中,哪些該歸入控制邏輯中了,該方法我在兩年前的一篇文章中提到過,大家感興趣的
話可以看看這個鏈接, 採用[ICONIX] 方法實踐BLOG設計之四 [健壯性分析] .
     
其核心內容如下:   

複製代碼

   實體對象(entity object):
         通常是來自域模型中的對象(也就是現實世界),它常對應於數據庫表和文件,這些數據表
   和文件中存儲了執行用例所需的數據。有些實體對象是“臨時”對象(如搜索結果),當用例
   結束後將消失。

   邊界對象(boundary object):
         參與者使用它來同系統交互,這通常包含窗口,屏幕,對話框和菜單。如果有GUI原型,
   將會知道許多主要的邊界對象是什麼。

   控制對象(control object):
         將邊界對象和實體對象關聯起來(通常被稱爲控制器,因爲它們通常不是真正的對象),
   它包含了大部分應用邏輯,它們在用戶和存儲的數據之間架起一座橋樑。控制對象中包含經常
   修改的業務規則和策略。這樣修改只需要在這些對象中進行,而不會涉及到用戶界面和數據庫
   模式。控制器偶爾 (20%的時間內)也會是設計中的“真正對象”,但大部分時間內,控制器只
   是一個佔位符,用於避免您遺漏用例要求的任何功能和系統行爲。

複製代碼

  

      上面的三個對象分別對應Model, View, Controller.
     
      正如文中所說,該方法還提供瞭如下好處:    

   1.它幫助您確保用例文本的正確性,且沒有指定不合理或不可能的行爲 (基於要使用的一組對
     象),從而提供了健康性檢查。
   2.幫助確保用例考慮了所有必需的分支流程,從而提供了完整性和正確性檢查。
   3.讓您能夠(持續)發現對象,因爲在域建模期間可能會遺漏一些對象, 而這些對象在繪製時
     序圖時不易被發現,並且很可能正是它導致無法繪製時序圖。
   4.縮小分析和設計的鴻溝,從而最終完成初步設計(關於初步設計複覈會在下一篇中介紹)。

 

      六.MVC與MVP是否可以同時出現在一個SLN甚至一個項目中   
      這一點我想誰說了都不算數,只有用戶需求才是王道,用戶使用在當前項目中實現某些特定
功能,而該功能恰恰是MVC或MVP的用武之地,那就一個字:“”。

 
      最後還要再說明一點:
   
      
業務邏輯是系統架構中體現核心價值的部分。它的關注點主要集中在業務規則的制定、業務流程
的實現等與業務需求有關的系統設計,所以說一個系統來說,業務邏輯是無處不在的。View上的是顯
示邏輯,Controller上是流程控制邏輯),Model上簡直就是“邏輯大本營”了。
    
 

      使用 MVC 框架時我們要將“經常變化”的業務規則(位於Controller)和相對穩定的業務邏輯
(位於Model)分離開,同時在Model層採用接口方式實現,以此來應對將來不斷變化的業務需求。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章