MVC

MVC模式。MVC模式最早由Trygve Reenskaug在1978年提出，是施樂帕羅奧多研究中心在20世紀80年代為程式語言Smalltalk發明的一種軟體架構。MVC模式的目的是實現一種動態的程式設計，使後續對程式的修改和擴充套件簡化，並且使程式某一部分的重複利用成為可能。除此之外，此模式透過對複雜度的簡化，使程式結構更加直觀。軟體系統透過對自身基本部分分離的同時也賦予了各個基本部分應有的功能。專業人員可以依據自身的專長分組：元件的互動.將應用程式劃分為三種元件，模型 - 檢視 - 控制器設計定義它們之間的相互作用。優點.在最初的JSP網頁中，像資料庫查詢語句(SQL query)這樣的資料層程式碼和像HTML這樣的表示層程式碼是混在一起。雖然有著經驗比較豐富的開發者會將資料從表示層分離開來，但這樣的良好設計通常並不是很容易做到的，實現它需要精心地計劃和不斷的嘗試。MVC可以從根本上強制性地將它們分開。儘管構造MVC應用程式需要一些額外的工作，但是它帶給我們的好處是毋庸置疑的。首先，多個 View 能共享一個 Model 。如今，同一個Web應用程式會提供多種使用者介面，例如使用者希望既能夠透過瀏覽器來收發電子郵件，還希望透過手機來訪問電子郵箱，這就要求Web網站同時能提供Internet介面和WAP介面。在MVC設計模式中， Model 響應使用者請求並返回響應資料，View 負責格式化資料並把它們呈現給使用者，業務邏輯和表示層分離，同一個 Model 可以被不同的 View 重用，所以大大提高了程式碼的可重用性。其次，Controller 是自包含的物件，與 Model 和 View 保持相對獨立，所以可以方便的改變應用程式的資料層和業務規則。例如，把資料庫從MySQL移植到Oracle，或者把RDBMS資料變成LDAP資料只需改變 Controller 即可。一旦正確地實現了控制器，不管資料來自資料庫還是LDAP伺服器，View 都會正確地顯示它們。由於MVC模式的三個模組相互獨立，改變其中一個不會影響其他兩個，所以依據這種設計思想能構造良好的少互擾性的構件。此外，Controller 提高了應用程式的靈活性和可配置性。Controller 可以用來連線不同的 Model 和 View 去完成使用者的需求，也可以構造應用程式提供強有力的手段。給定一些可重用的 Model 、 View 和Controller 可以根據使用者的需求選擇適當的 Model 進行處理，然後選擇適當的的 View 將處理結果顯示給使用者。評價、誤解及適用範圍.MVC模式在概念上強調 Model, View, Controller 的分離，各個模組也遵循著由 Controller 來處理訊息，Model 掌管資料View 負責資料顯示的職責分離原則，因此在實作上，MVC 模式的 Framework 通常會將 MVC 三個部份分離實作：也因為 MVC 模式強調職責分離，所以在發展 MVC 應用時會產生很多檔案，在 IDE (整合開發環境) 不夠成熟時它會是個問題，但在現代主流 IDE 都能使用類別物件的資訊來組織程式碼編輯的情況下，多檔案早已不是問題，而且 MVC 模式會要求開發者進一步思考應用程式的架構 (Application Architecture)，而非用大雜燴的方式開發應用程式，對於應用程式的生命週期以及後續的可擴充與可維護性而言有相當正面的幫助。另外，MVC 職責分離也帶來了一個現代軟體工程要求的重要特性：可測試性 (Testability)，MVC-based 的應用程式在良好的職責分離的設計下，各個部份可獨立行使單元測試，有利於與企業內的自動化測試、持續整合 (Continuous Integration) 與持續交付 (Continuous Delivery) 流程整合，減少應用程式改版部署所需的時間。MVC 模式的應用程式的目的就是希望打破以往應用程式使用的大雜燴程式撰寫方式，並間接誘使開發人員以更高的架構導向思維來思考應用程式的設計，因此對於一個剛入門的初學者來說，架構導向的思考會有一定的門檻，需要較多的實作與練習才能具備相應的能力，大多數的初學者還是較習慣於大雜燴式的程式撰寫，所以可能會對 MVC 模式抱持著排斥或厭惡的心態，然而 MVC都是有助於應用程式長遠的發展，雖然大雜燴式的程式也可以用來發展長生命週期的應用程式，但是相較於 MVC，大雜燴式的程式在可擴充性和可維護性 (尤其是可測試性) 上會遠比 MVC 複雜很多，相反的，MVC 模式的應用程式是在初始開發時期必須先思考並使用軟體架構，使得開發時期會需要花較多心力，但是一旦應用程式完成後，可擴充性、可維護性和可測試性反而會因為 MVC 的特性而變得容易。因此，MVC 模式在已有眾多優秀 Framework 的現代，早就已經沒有不適合小型應用的問題，小型的應用還是可以由 MVC Framework 的應用來獲取 MVC 的優點，同時它也能作為未來小型應用擴充到大型應用時的基礎與入門磚。若一開始就想要做大型應用，那麼 MVC 模式的職責分離以及要求開發的架構思考會更適合大型應用的開發。實際範例.這裡有一個透過 JavaScript 所實現的基於 MVC 模型，需要注意的是：MVC 不是一種技術，而是一種理念。/** 模擬 Model, View, Controller */var M = {}, V = {}, C = {};/** Model 負責存放資料 */M.data = "hello world";/** View 負責將資料輸出給使用者 *//** Controller 作為連線 M 和 V 的橋樑 *//** 在網頁讀取的時候呼叫 Controller */window.onload = C.handleOnload;在這個簡短的程式中就是一個完整的 MVC 模式。實現.MFC.微軟所推出的MFC Document/View架構是早期對於MVC模式的實現，MFC將程式分成CView以及CDocument兩大類別，其中的Document對應MVC中的 Model ，View 相當於MVC中的 View＋Controller，再加上CWinApp類別，合成三大項。但是基本上MFC是一個失敗的MVC模式作品。由於MFC之下的Document/View 定義過於模糊，未將Controller部份取出，因此 Controller 可以置入 View 或Document，但不管置入哪一方面，都會與View或Document綁死，沒有彈性。Java.Java 平臺企業版 (J2EE).和其他的各種框架不一樣，J2EE為模型物件定義了一個規範。在J2EE應用程式中，檢視可能由Java Server Page(JSP)擔任。生成 View 的程式碼則可能是一個servlet的一部分，特別是在客戶端服務端互動的時候。J2EE應用中，Controller 可能是一個servlet。除了可直接以J2EE來撰寫外，亦可用其他框架來撰寫，常見的有Struts2、Spring Framework……等等。Model 則是由一個實體Bean來實現。Java Swing.Swing是一個標準的MVC結構。ComponentUI代表View，負責描畫元件。元件尤其Model層，比如JTextField的Document、JTable的TableModel、JTree的TreeModel等等。Control可能不是很明顯，我們可以將Event機制看作Swing團隊為開發者設計的Controller。作為Java開發者，如果想理解MVC的結構，學習Swing的確是個不錯的選擇。.NET.ASP.NET.在ASP.NET中，針對檢視則留給開發者去設計。ASPX和ASCX檔案被用來處理 View 的職責。在這個設計中 View 實際上是從 Controller 繼承而來。這個和Smalltalk的實施有所不同，在Smalltalk中不同的類都有指標互相指向對方。Controller 的職責被分割成兩部分。事件的產生和傳輸是框架的一部分，更明確的說是Page和Control兩個類。而事件的處理則在分離的程式碼中實現。一般說來，控制器是部件，用來處理使用者互動、對model施加工作、最終選擇view來繪製。對於MVC應用程式，view只顯式資訊；控制器處理和響應使用者的輸入和互動。ASP.NET 不嚴格需要一個 Model。開發者可以自行選擇建立一個 Model 類，但是很多人選擇放棄這一步，直接把事件處理放在 Controller 裡處理任何計算、資料儲存等等。但用 Model 來包含商業邏輯和資料存取是可實現的。一般說來，MVC應用程中的Model表示應用程式的狀態、應用程式能執行的任何業務邏輯或操作。強型別的views典型使用ViewModel型別來包含顯示在該view中的資料。控制器從model建立並保有這些ViewModel例項。ASP.NET MVC.2013年10月17日ASP.NET MVC發表了穩定版本5.0。在ASP.NET MVC中，一般情況下Model通常搭配LINQ to SQL類別來實作。ASP.NET Core MVC.隨著.NET Core的釋出，2016年5月17日釋出了ASP.NET Core MVC 1.0.0-rc2。現已發展為ASP.NET Core MVC 6。Windows Forms.在WinForms中，這個針對檢視則留給開發者去設計。由Form或者Control類繼承來的一個類處理 View 的職責。在WinForm這個例子中 View 和 Controller 被編譯在同一個類中，這個和ASP.NET不同。Controller 的職責被分割成三部分。事件的產生和傳輸是作業系統的一部分。在.Net框架中Form和Control類將不同的事件轉發給相應的事件處理器。而事件的處理則在分離的程式碼中實現。就像ASP.NET一樣，WinForm不嚴格需要一個 Model。開發者可以自行選擇建立一個 Model 類，但是很多人選擇放棄這一步，直接把事件處理放在 Controller 裡處理任何計算、資料儲存等等。也就是說用Model來包含商業邏輯和資料存取。Perl.Catalyst和Jifty是透過Perl語言所開發出來的Web Framework，都採用Model-View-Controller 架構。Catalyst 本身只是做了 Controller，View 和 Model 讓開發者自由選用 CPAN 上的模組開發，例如 Template 和 Template Declare 都可用來產生檢視。Jifty 將 MVC 完全實做完成，View 的部份在早期版本使用 Mason 實做，較新版本使用 Template Declare。Ruby on Rails.Ruby on Rails是透過Ruby語言所開發出來的 Web Framework，也是採用 Model-View-Controller 架構。Model 部份使用 Active Record 概念實做，加上 Migration 機制，使得其 Model 結構非常容易控制。Python.Python 有許多的 MVC 架構。最常用的有 Django 和 TurboGears。