來自:http://www.cnblogs.com/xiaozhi_5638/p/4019065.htmlhtml
ASP.NET Webforms Behind Code的好處和存在的問題編程
ASP.NET Webforms是一個RAD/VISUAL(快速可視化)的Web程序開發技術。也就是說,開發者簡單地拖拽控件到窗體設計器上,VS就會在Behind Code(aspx.cs文件,譯者注)生成代碼。瀏覽器
換句話說,你向設計器中拖放一個Button按鈕後,即可以在它的事件處理程序中編寫代碼了。服務器
Behind Code文件就是開發者可以快速開發Webforms程序的關鍵,由於它封裝了底層複雜的技術過程,如event、delegates、HTTP協議Post、Get以及Session管理等等。你能夠閱讀這篇博客Why Microsoft has partial classes(雖然本文反對者居多,可是我以爲仍是有一些道理,譯者注),瞭解微軟在UI設計方面取得成功的故事。架構
但正是Behind Code的工做方式給開發Web程序帶來了5個嚴重問題,下面咱們來討論一下這5個問題以及MVC是怎樣解決這些問題的。函數
問題1:使用「基於視圖」的解決方案去應對「基於行爲」的需求佈局
Web網站最終是給終端用戶使用的,終端用戶帶着特定的目的去訪問一個網站,而後他們使用一些「行爲動做」(好比輸入URL、點擊提交按鈕等等,譯者注)來表達他們想要幹什麼。好比一我的去購物網站購物,那麼他會經過如下行爲來表達他想幹什麼:單元測試
以上這些行爲就會經過相似點擊按鈕、右鍵或者在瀏覽器地址欄中輸入URL來完成。正是由於以上這些行爲的構成特色,因此Web程序選擇使用HTTP協議,由於該協議包含了許多與之類似的動做諸如POST、GET、PUT以及DELETE等等,這些偏偏能更形象地表達終端用戶的意圖。這樣很天然地,咱們要是可以把用戶的這些行爲一一映射到咱們程序方法(函數)上,這不只會更有意義還會使項目架構更加清晰明瞭。學習
可是,微軟沒法這樣去作。由於微軟一直想推廣它的「快速應用程序開發」(RAD)的概念(或者咱們也能夠稱之爲「可視化編程」),因此它最終選擇了一個「基於視圖」的解決方案去應對「基於行爲」的需求。測試
如上圖所示,用戶的「請求過程」呈現出一個古怪的路線(見上圖)。
如上,微軟搞出了一個「基於視圖」的架構方案去應付一個「基於行爲」的需求。換句話說,若是一個終端用戶發出了一個「購買」的請求,那麼該請求先被一個相似「Shopping.aspx」的頁面進行處理,而後該頁面再去通知相似「Shopping.aspx.cs」,接着開始一個複雜的頁面生命週期,最後激發對應事件(Page.Load,Button.Click)進行請求處理而後將結果返回給終端用戶。
上面這個過程至關複雜繁瑣,終端用戶的任何一個請求都是須要先通過一個複雜的頁面生命週期以後才能真正被處理。那麼,咱們建立一個「面向行爲」的架構方案去取代「面向視圖」怎麼樣?
若是咱們先處理請求,而後再呈現視圖給終端用戶,這個流程是否是要更清楚明瞭一些呢?事實上,MVC就是這樣作的,用戶請求先被對應的Controller處理,而後再由後者呈現對應的View(附帶Model)。
問題2:壞的架構模式帶來的反作用:緊耦合
一旦你選擇了一個下三濫的架構模式,你後期會爲了適應它而不斷地作出妥協,最終出現愈來愈多的負面效果。ASP.NET Webforms偏偏就是這樣的。Behind Code(aspx.cs文件,譯者注)歷來都不會真正地符合「鬆耦合」的規則,好比ASPX.CS文件永遠不能與ASPX文件分離開來。
換句話說,咱們不能輕易地將「Customer.aspx.cs」和「CustomerDetailed.aspx」組合到一塊兒,Behind Code和視圖僅僅關聯在一塊兒,不能被複用。
若是你比較過Behind Code代碼和項目中其它模塊代碼,你會發現前者不但體積龐大並且還充斥着不可勝數的事件處理程序代碼。這不只使代碼不易閱讀,後期維護更是難上加難。
若是咱們將「視圖優先」的架構方案換成「行爲優先」的方案,咱們就很容易地重用一部分邏輯代碼,而且呈現給最終用戶的視圖能夠隨意切換。好比,若是一個終端用戶發送一個「Display」的請求,那麼咱們能夠選擇將「DisplayDesktop.aspx」或者「DisplayMobile.aspx」發送給終端用戶,而這徹底取決於用戶當前使用設備。
在MVC中,咱們能夠很輕鬆決定到底顯示「MobileView」仍是「NormalView」,你能夠想象,在Webforms中,實現這個是多麼複雜。
問題3:HTML並非服務器返回數據的惟一格式
在Webforms中,視圖和Behind Code不只處於一種「緊耦合」狀態,就連服務器返回的數據格式也是至關固定的,默認爲HTML。若是你想要改變返回數據的格式,那麼你得和Content-Type以及Response.End方法打交道了,這是一件多麼頭疼的事情。
事實上,若是咱們使用「行爲優先」的方案,在處理完用戶請求後,就有很大機會去決定到底給用戶返回什麼格式的數據。下面是一段MVC根據傳進來的參數來決定到底返回JSON仍是HTML給用戶的代碼。這種靈活性在Webforms中幾乎很難實現。
問題4:「視圖」與「數據」的靈活組合(這裏實際上是指MVC的優勢,譯者注)
當咱們給用戶一個Response時,其實包含View和Data兩部分(View表明頁面結構,Data表明頁面數據,譯者注)。Webforms是一個「視圖優先」的架構模式,因此它很難靈活地切換最終呈現給用戶的視圖,不斷如此,視圖還要負責調用邏輯處理的代碼,這徹底違背了單一職責原則(SRP)(詳細的SOLID五大設計原則請參見博主前面博客,譯者注)。
若是咱們使用「行爲優先」的架構模式,那麼當請求到達時,先通過處理,再才決定呈現給用戶什麼視圖和數據。
MVC中,在處理請求時,你能夠編寫以下代碼。你能夠將同一個Model(數據,譯者注)與不一樣的View進行組合。以下面代碼中所示,你能夠將一個Model(customerdata)與一個View(DetailCustomer)組合,也能夠將它與另外一個View(Customer)組合。
這種靈活性在Webforms中是很是難以實現的,由於在Webforms中,請求先到達視圖(Page頁面,譯者注),而後由它決定調用什麼處理邏輯。視圖在一開始就決定死了。
問題5:將Behind Code代碼定義成一個普通類有利於單元測試(這裏實際上是指MVC的優勢,譯者注)
在Webforms中,Behind Code代碼以一個Partial類的形式出現,它至關複雜(繼承自Page類),並且不能輕易地建立它的實例。默認狀況下,每一個頁面均繼承自Page類,因爲Page類依賴項比較多,因此實例化一個Web頁面對象至關困難(這裏指單元測試的時候,譯者注)。
如今你可能會問,爲何你要本身實例化一個Page類對象?緣由很簡單,由於我要進行單元測試,我要測試按鈕Button1的Click事件處理程序(Button1_Click)是否按照個人預期那樣去執行。
可是問題來了,若是你按照如下方式去編寫測試代碼,它會拋出異常
這使得UI這塊的單元測試很是困難:
在MVC中,Behind Code變成了簡單正常的類(Controller中的各類Class,譯者注),建立這些類實例沒有以前那麼費勁。
MVC真是解決以上問題的有效方案?
將「基於視圖」的架構轉變爲「基於行爲」的架構,咱們須要作如下幾個修改(見上圖):
那麼,使用MVC架構後,
ASP.NET Webforms最大的優點就是RAD和VISUAL(快速可視化開發),即便如今看來它是那樣的繁瑣和不堪入目,但它確實可以讓你的程序開發速度加快,準時完工(不考慮其餘後果,譯者注)。
在2000年,微軟推出ASP.NET Webforms是一個正確的決定,由於那時候它想吸引那些已經熟悉VB六、VF、VC++等快速開發技術的開發人員,我認爲Webforms已經達到了它原來的目的。如今咱們是時候邁開腳步去學習更好的架構模式了,好比MVC(對應的ASP.NET MVC,譯者注)。