ASP.NET MVC - 什麼是MVC?

28 September 2011 — Written by Sky Chang
#ASP.NET MVC#Design Patten

還記得當年,第一次看到MVC,是從Java那邊看來的,但是實作,卻是PHP的Zend Framewrok,後來,隨著工作關係,又回到了Microsoft,而也因為工作的關係,整整的經歷過ASP、ASP.NET、ASP.NET MVC,三個跨時代產品XD,所以恐怖的義大利麵也吃過,萬行Fuction包含百行SQL也碰過,不過也不能怪罪於先人,畢竟,幾十年歷史的系統,軟體發展又那麼快,這中間的演變真的很大,當初也沒有什麼比較好的設計方式,所以這也是可以諒解的。

隨著時間的演進,程式設計也像神奇寶貝一樣,會開始超進化,只不過不是程式自己進化,而是許多偉大的程式設計師在撰寫程式時,發現了許多的問題,於是提出好的設計架構,而MVC就是其中一個。

還記得第一段提到的義大利麵程式碼嗎?在解釋MVC之前,先解釋一下義大利麵程式吧,所謂的義大利麵程式碼,就是一隻程式裡面,包山包地也包海,最有名的大概就是ASP吧,HTML包在裡面,JavaScript包在裡面,CSS包在裡面,還有一堆邏輯也包在裡面,別忘了,還要加一下配料SQL….;維護過的人就知道,光是要拆解,就費勁功夫了,忍痛改完,就算驗證過,還是常常發生一堆錯誤,然後又進入這可怕的循環;記得以前在公司,有好幾支這種地雷,每次有需要動到這些地雷的時候,大家覺得都會唯恐避之不及。

後來出了ASP.NET,我只能說,微軟真的是封裝得太棒了,能把整個技術封裝成這種程度,讓人開發網頁像是開發Win Form程式一班,而且針對視圖與邏輯也有一定程度的拆解,但隨著時代的轉移,現在越來越標準的HTML、CSS,還有AJAX的崛起,測試的重要性等,也讓ASP.NET的一些缺點暴露出來,如下:

  1. 傳輸過於笨重
  2. 複雜的HTML
  3. 不可測試性

ASP.NET是利用View state來處理整個生命週期,但View state實在是太重了,而且生命週期也太過複雜,PostBack到最後都不知道在做甚麼,對高手來說,可能沒有此困擾,但對於新手來講,這反而是一個開發上的一個隱憂,此外因View state過大,傳遞也會浪費許多的時間,雖然現在隨便就幾百Mb,但不可否認的,如果是大型網站,還是必須將此考量進去。

其次就是分離觀點的問題,ASP.NET變成在後端去控制前端元件,這在測試上,也是另外一種困擾,因為這樣子就很難單獨的測試到邏輯。

最後,用過ASP.NET的人都知道,很少人會自己寫標準的HTML在ASPX頁面,幾乎都是利用拖拉元件方式,並使用這些元件,而這也會形成另外一個問題,由ASP.NET產生出來的html,擁有複雜的id,而且可能不是標準的html。

當然這些問題隨著ASP.NET 4的發佈,也慢慢地改善,但畢竟先天就是這樣子了,後天再怎樣改善,還是沒辦法改到根本。

通常講到這,就一定會有人詢問,那ASP.NET就完全沒用了嗎?要被淘汰了嗎?其實Microsoft也說過,ASP.NET 還是會持續維護,而且在實際的應用上,ASP.NET還是很好用,像我們以前必須要非常快速的開發一個一兩頁的小程式,我們就很喜歡用ASP.NET快速的處理完畢,甚至有一些是拋棄式的網頁,我們也喜歡用ASP.NET快速開發;對的地方用上對的工具,才是最重要的,你說是吧!

拉哩拉哩的說了一堆古,MVC都還沒帶出來哩,這邊我們就隆重的介紹一下MVC吧,MVC是一種軟體架構的設計樣式,不只是微軟有用,PHP裡面也有許多的Framewrok來實作MVC架構( 例如Zend Framework ),連Flash也有MVC架構,而微軟實作MVC的產品,就叫做ASP.NET MVC。所以MVC是一個軟體架構的設計樣式,ASP.NET MVC是微軟實作此架構的名詞。

而MVC是由以下三個單字的第一個字母所組合而成的。

  1. Model – 資料、商業物件。
  2. View - 視圖,包含畫面、顯示的邏輯。
  3. Controller - 控制整個運作的流程。

若把它拆解開來,HTML、CSS、JavaScript等,就是屬於View,他負責顯示那些畫面,也負責處理畫面的邏輯,所以你不會在上面看到一堆SQL,但你還是會看到一些關於顯示上的邏輯。

而那些商業物件,就是Model,你可以把他當作是資料,但實際上,他應該是一種擁有商業邏輯方法的物件。

而Controller就是控管整個流程,他會控管接下來的路要怎麼走;當然也可以將SQL塞到Controller裡面,但是非常不推薦;Controller應該定義的是處理的步驟,但細節的資料庫存取,或是商業邏輯,因該要拆分到其他各自負責的物件去( 例如Repository、或是Model等 )。

說到這邊,可能已經湖煞煞了,但是沒關係,這邊只是給個觀念,後面會比較詳細的說到,現階段只要知道View是畫面,Model是資料,Controller是流程就可以了。

這裡有一張MVC,三個之間的關係。

image

所以我們可以發現,Controller會相依於Model和View,因為Controller要將Model取回,並傳遞給View,而View因為要顯示Controller傳過來的Model,所以相依於Model,而Model則可以完全獨立;也因此,MVC這種架構,大大的降低偶合,並提高了內聚力,所以MVC最大最大的優點就是可以很輕鬆的拆解,並且彼此可以獨立開發,測試達到關注點分離的設計境界。

所以當一個Team,可以有人專注於開發Model,有人專注的開發View,有人專注地開發流程,並且在測試的時候,獨立進行,這部分就是ASP或是ASP.NET比較難做到的事情了。

(要測試ASP.NET的一個按下按鈕的功能,然後不要用到View….老實說,真的是有點困難… )

所以,所謂的MVC,就是將原本混再一起的東西,做了拆離,讓我們能專注的處理每個部份。

提到這邊,有人會開始詢問到,MVC不就是三層式架構嗎( 3-Tier )?

早期的多層式架構,是應用於Server的溝通上面,因一台Server效能的瓶頸,或是維護上的問題,所以拆成多層來處理;後來開始有人將此概念延伸到軟體層上,3-Tier是將軟體分為展示( UI ),邏輯 ( BI ) , 資料存取( DA )等;的確,對應上看起來的確很像MVC,但我必須強調,N-Tier不等於MVC,因為MVC是實作於展示層的設計樣式,所以不要把N-Tier和MVC混為一談,也不要一直想著怎樣對應,因為兩者是講不同的東西。所以N-Tier和MVC不相等,也不要想著怎樣去對應。

接下來,我們知道這三個東西後,現在我們用一個簡單的登入系統來看看,他的流程是怎樣跑,第一步當然是先在瀏覽器上打上網址,假設是index好了,後面的程式收到你的訊息後,第一個動作的是Controller,Controller根據你打的網址,並會知道要傳怎樣的View給你看,而你看到畫面上有id和pw欄位需要輸入,並輸入進去後,按下送出,View就會將你輸入好的東西( Model )送回到Controller去做處理。

( 這裡補充一下,原則上,過程是很複雜,但有些東西是後面才會提到,所以上面敘述的是非常簡易的版本,讓大家先有一點感覺。理論上我們會先建立客戶這個物件當作Model,在輸入完index此頁面的時候,Controller並會吐回一個View給使用者,而這個View並會使用客戶這個Model,當使用者填完id、pw的時候,並會將此資料塞到客戶這個Model,並傳回Controller,Controller會再利用Repository此樣式去做資料庫的存取,來驗證是否正確,如果正確就導向到正確頁,如果錯誤就導向到錯誤頁。 )

基本上,整個MVC的流程大致上就是這樣,其實MVC這個Patten,就是來解決原本複雜的交互依賴問題,而利用了MVC進行拆離,來提高整體的維護,在ASP.NET MVC推出後,我們也實作了許多案例,無論是在開發上的清晰度,或是後續的維護,合作等等,都有一種煥然一新的感受,當然,內部同仁也有人抱怨,沒像ASP.NET那樣拖拉的方便、覺得要處理許許多多的東西,但這些其實也只是因為大家不熟悉而產生的抱怨,到後來,大家也都開開心心的活在ASP.NET MVC之中了。

最後,國外的ASP.NET MVC書籍作者給了他一段評言。

It emphasizes clean architecture, design patterns, and testability, and it doesn’t try to conceal how the Web works.

中文的意思是,"它強調簡潔的架構,設計模式,和可測性,它不試圖掩飾如何在Web上的運作"。

沒錯,這就是ASP.NET MVC,後續,我們將開始講解如何開發ASP.NET MVC。

Sky & Study4.TW