2012-01-14 130 views
6

任何人都可以舉一個例子,說明爲什麼使用MVC而不是簡單的模型和視圖纔是有利的。模型 - 視圖 - 控制器(MVC)優於模型 - 視圖的優點是什麼?

注意:無論是MVC還是MVP(Model-View-Presenter),我都在談論視圖接收輸入的地方,然後控制器會通過解釋輸入事件來響應輸入事件,由模型完成。當模型改變時,視圖將通過響應來自模型的事件來自我更新。

什麼是不利的只是讓模型對活動作出響應的視圖,反之亦然?

在MVC中,如果我在那個影響控制器然後我就要做在控制器的變化的方式改變了模型。在模型視圖中,如果我更改模型,我將不得不更新視圖。

因此,看起來我們通過添加「控制器」部分來引入複雜性?

回答

4

在MVC中,模型忽視它的環境,認爲可能是太 - 假冒(盲目地)將其事件傳遞給控制器​​,控制器更瞭解視圖和模型。所以當所有內容都說完之後,控制器就是系統中「不可重複使用」的一次性部分,因爲它是最能感知上下文的組件。

,如果我改變了影響控制器的方式模型...

的模型應該暴露在這樣​​簡單的CRUD方法,那些使用方法不必一無所知關於傳遞的更新對象,以及模型內真正發生的事情。

這意味着視圖,國際海事組織,通過產生傳遞記錄做了一些工作,因爲控制器應該是無狀態的,認爲是更持久。控制器被觸發並且「踢入」用傳遞的對象完成他們的工作並且沒有狀態。

傳遞的數據是通過某種通用約定創建的。

讓我走得更遠。假設你有一個視圖,一個tablegrid和一個控件,它的啓用屬性依賴於item在網格中被選中 - 你可以創建一個處理這些控件和內部邏輯的視圖,這可能是要走的路在這樣一個簡化的例子中。

但是,你的觀點越原子化,它們變得越可重用,所以你爲每一個,每一個控制都創造了一個視圖。現在,您正在查看視圖必須瞭解彼此的情況,才能爲正確的通知註冊自己...

這是控制器的步驟,因爲我們要將所有這些依賴關係粘貼到他身上,長期的一次性用品。所以控制器管理這種類型的視圖通知方案。

現在你的觀點是無知的,因爲它們可以是獨立的,因此可以重複使用。

您可以編寫視圖,而無需瞭解系統或「業務邏輯」,因爲他們喜歡稱之爲。你可以編寫一個模型,而不必知道你的目標太多(儘管它有助於調整模型,使其能夠返回你想要的數據集)......但是控制器,它們是最後一個,你必須擁有之前的兩個確定之前,你可以將東西連接在一起。

下面是另一個需要思考的問題 - 就像模型應該抽象並提供一個通用接口來管理它所管理的數據的底層實現一樣(客戶端不知道數據是否來自數據庫,文件,程序設置等) - 視圖還應抽象出它正在使用的控件。

因此,最終,這意味着一個視圖不應(下面警告)具有的功能/性能看起來像這樣:

public property BackgroundColor{get;set} 

也不

public function ScrollBy(x,y){} 

但是代替:

public SetProp(string name, object val){} 

And

public DoCmd(string name, object val){} 

這是有點人爲的,記住我最終說過......你問爲什麼這是一個好主意?考慮到你可能總有一天想將某些東西從WinForms移植到Flex,或者簡單地想使用一個新的控制庫,而這個控件庫可能不會暴露相同的功能。

我在這裏說'端口',但這實際上不是目標,我們不關心移植這個特定的應用程序,而是讓底層的MVC元素具有足夠的通用性,足以傳遞到新的風格 - 在內部,離開一致且能力獨立的外部接口完好無損。

如果你沒有做到這一點,那麼當你的新口味出現時,你在所有(可能可重用/可重構/可擴展)控制器中查看屬性的硬引用必須被忽略。

這並不意味着這樣的通用setter和cmds必須是所有視圖能力的接口,而是他們應該處理'edge case'屬性以及可以在傳統中暴露的普通道具/ cmds硬連接的方式。把它想象成一個'擴展屬性'處理程序。

這樣,(再次設計),假設您正在構建一個框架,其中的按鈕不再具有buttonIcon屬性。這很酷,因爲你有先見之明來創建一個按鈕視圖界面,​​其中buttonIcon是一個擴展屬性,在視圖中,當條件代碼接收到set/get時,它現在不做任何操作。總之,我想說的是,MVC的編碼目標應該是爲模型和視圖的通用接口賦予它們的底層組件,所以當你編寫一個控制器時,你不必認真思考你是誰控制的。而且,雖然控制者正在(似乎是不公平地)成爲重複使用的長期犧牲品 - 但這並不意味着所有的控制者都註定要死亡。因爲他們的許多'思想'已經被推到了半智能的模型和視圖以及其他控制器(例如:控制器對網格進行排序或操縱樹視圖) - 因此他們很小,他們希望很小,可以很容易地查看並且有資格在您的下一個項目中重新使用 - 或者克隆並調整爲適合。 MVC/P的

+0

我給出一個簡單的例子,說明爲什麼我沒有看到優勢。假設我們正在談論一輛汽車。點擊Car View的加速按鈕,Controller通過調用Model.Accelerate()來響應,然後Model的速度發生變化,View響應Model事件並更新屏幕上的速度讀數。現在,在模型視圖(MV)按鈕點擊時,視圖調用Model.Accelerate()和相同的情況發生沒有涉及控制器。在MVC,如果我改變加速()爲IncreaseSpeed()我將不得不更新控制器調用這種方法。在MV的情況下,我會做同樣的更新,但視圖。 – 2012-01-16 16:24:24

+0

繼續以前的評論:因此,這些優點僅適用於以下情況:1.您的觀點並不特定於您當前的項目(這很罕見)。我想不出任何! (可能缺乏經驗)。 – 2012-01-16 16:31:45

+0

你有一個1對1的例子。該視圖必須瞭解所有關於模型的EVERY WAY模型。這是所有依賴項的集合。而對於控制器來說,這個叢是分開的 - 每個事件都有一個單獨的控制器 - 並且如果事件中的模型必須發生更奇特的事情,那麼控制器中會發生變化(即控制器的潛在再利用的可能性會增加僅適用於一個事件)。用你的方式,每個增強/添加都會減少視圖的可重用性。 – 2012-01-17 04:19:16

1

它實際上通過將工作流程邏輯與領域邏輯分離來降低複雜性。它還使編寫單元測試更容易,並使應用程序更易於維護和擴展。

想象一下,如果您想添加新的數據類型。使用上述方法,您可能會複製新類中的許多工作流程邏輯,因爲它可能會與域邏輯緊密耦合。

參與工作流邏輯分離到控制器的紀律使得它更有可能的是,你將有工作流程和邏輯域之間的依賴較少。添加新的數據類型將變得更加簡單,您可以創建新的域對象並查看可以重複使用多少控制器,例如通過從控制器超類繼承。

這也將使其更容易改變框架在未來的 - 模型可能不會有太大變化,因此會更加便於攜帶。

說了這麼多,你可能要考慮MVVM取決於你使用的是什麼作爲您的表示層:Benefits of MVVM over MVC

1

優勢(我說的是監督控制器這裏)在MV包括:

  • 您可以處理複雜的數據控制器綁定代碼,如果需要的話。

  • 您可以在沒有UI測試框架的情況下測試複雜的表示邏輯。

  • 您還可以讓圖形設計師製作您的視圖,而不是看到您的代碼,並且在修正視圖時不會弄亂您的代碼。