MVC在WEB開發中用於界定工做屬於Server端仍是WEB前端仍是十分清晰的。這也就是你們目前常見的MVC設計模式:html
View<===>Controller<===>Model前端
即Controller做爲粘合劑分別於View和Model進行雙向通信。設計模式
我也一度認爲這就是經典MVC設計模式,雖然我一直知道MVC設計模式的起源是開發客戶端應用。但當我在作一個iOS移動端應用架構設計時發現,若是沿用Model到View的通信必須藉助Controller,那麼一些數據變動引起View顯示變動的場景的實現是十分困難的。因而我增長了一種Model===>View單向通信的方式,藉助一種特殊用途的對象:ModelView。稍後我會說明ModelView和MVVM中ViewModel的類似與不一樣。架構
在寫這篇文章前,我再次翻閱MVC設計模式的介紹時發現,原來WEB-MVC是經典MVC的變形,也就是說,在經典MVC中,Model的設計是能夠向View進行單向通信的,原文以下:mvc
原文參見:Developing Backbone.js Applications:Smalltalk-80 MVCapp
所以我發現,我設計和使用的MMVVC設計方法其實就是經典MVC設計模式,只是對View、Controller、Model的概念又作了更細的分解,以便更好的實現模塊複用,以及實現View、Controller、Model三層的開發解耦。dom
而後再看一段關於Smalltalk-80 MVC的設計意圖:ide
The idea was that decoupling these parts of the application would also allow the reuse of Models for other interfaces in the application.ui
也就是說,MVC中的Model是但願能夠被任何須要展現這部分數據的UI所複用的。爲何會有這個說明呢,是由於在那個年代,出現了這樣一種設計模式,原文說明以下:this
An approach known as Separated Presentation began to be used as a means to make a clear division between domain objects which modeled concepts in the real world (e.g., a photo, a person) and the presentation objects which were rendered to the user’s screen.
文中提到了兩類Object:
Domain Object:也就是MVC中的Model
Presentation Object:用於表示顯示數據的對象
MVC的一個設計意圖就是經過複用Domain Object,而不是再增長一個叫作Presentation Object的概念。
若是你熟悉MVVM中的ViewModel,你是否是會以爲,ViewModel就是一種Presentation Object?而MVC則是但願經過複用Domain Object來消除Presentation Object。
我之因此稱MMVVC爲一種方法,是由於其本質就是Smalltalk-80 MVC設計模式/架構。只是在MVC設計模式的Model、View、Controller分層上又作了進一步的分層,以便進一步實現View模塊的複用,以及實現Model、View、Controller三層的開發解耦(即一個客戶端功能的開發能夠由三個開發人員同時分別開發View層,Model層、Controller層)。
在MVC中已經很清晰的描述了,Model層是與其餘兩層解耦的,所以在MVC中Model層是能夠獨立開發的。但對View和Controller的定義比較模糊,並強調View和Controller是成對出現的,他們直接並無真正的界限。這就讓開發者對什麼屬於View,什麼屬於Controller有了自由的理解,從而加重了View和Controller中業務邏輯出現位置的混亂。
所以我在View和Controller之間,增長了一層ModelView,用來更加清晰明確的界定View和Controller,以及相關業務邏輯應屬於哪層:
經過上述分層和ModelView的引入,MMVVC方法對UI層相關業務邏輯的所屬位置進行了更爲明確的定義,將UI層相關業務邏輯分別劃分到了Controller和ModelView,這樣,不一樣的開發人員就能夠分別編寫一個功能所需的Model層業務邏輯、UI層業務邏輯、特殊需求的可複用View組件。
同時,經過對Model層以及View模塊進行合理的設計,甚至在開發一個新功能時,僅須要編寫UI層業務邏輯代碼(Controller和ModelView)。
ModelView與ViewController
在MVC設計模式的觀點中提到,View和Controller必定是成對出現的,Controller負責處理UI業務邏輯中的用戶事件,那顯然,UI業務邏輯中其他的業務邏輯(如ViewModel中定義的數據轉換邏輯)應隸屬於View。我的猜想在Smalltalk-80系統下,顯示邏輯的複雜程度應該是遠遠小於當今的,所以即使View的顯示邏輯歸屬於View也不會有問題,然而在當前View日益複雜的今天,特別是View組件的普遍使用,因而大量開發者開始將View顯示邏輯放在Controller中。這就是ModelView的做用:處理用戶顯示邏輯,將不屬於Controller中的顯示邏輯從新放回View層。
ViewController中的view屬性則可視爲爲一個ModelView。但在顯示組件使用方便的今天,爲每一個ViewController編寫一個ModelView類可能並非一個好的選擇,所以,咱們能夠在loadView中,經過代碼,或Storyboard來組裝出一個ModelView。僅在一個View須要對數據進行復雜處理邏輯時,或有複雜顯示邏輯須要處理時,編寫特定的ModelView類,並經過Controller將DO對象設置給這個ModelView。
同時,ModelView能夠與Model層耦合,以獲取數據,即原Controller中負責數據獲取的業務邏輯也應放在ModelView中,但ModelView不該處理用戶輸入(如對頁面數據修改後通知Model修改),這部分邏輯是Controller的職責。
ModeView與ViewMode
與ViewModel的相同點是,都負責處理對Mode層數據向顯示層數據的轉換邏輯。
不一樣點:
ViewModel:隸屬於Controller層(由Controller對象建立),屬於Presentation Object。
ModeView:隸屬於View層,實現爲View類(如UIView)的子類,可直接用於顯示。ModeView能夠調用Model中數據獲取的相關方法,獲取用於顯示的數據。
MMVVC方法是在Smalltalk-80 MVC設計模式的基礎上,經過增長ModelView層,對UI層中業務邏輯的編寫進行了更爲明確的定義:
經過將UI層業務邏輯的分離,爲實現View、Controller、Model三層的開發解耦提供了一種可能性。