MMVVC設計方法介紹:經典MVC設計模式在Cocoa-MVC中的一種實現方法

MVC介紹

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

  • A Domain element was known as a Model and was ignorant of the user-interface (Views and Controllers)
  • Presentation was taken care of by the View and the Controller, but there wasn’t just a single View and Controller. A View-Controller pair was required for each element being displayed on the screen and so there was no true separation between them
  • The Controller’s role in this pair was handling user input (such as key-presses and click events) and doing something sensible with them
  • The Observer pattern was used to update the View whenever the Model changed

原文參見:Developing Backbone.js Applications:Smalltalk-80 MVCapp

  • Model(模型)對象與UI層(Views和Controllers)對象解耦
  • 顯示控制由VIew和Controller共同負責,但他們並非獨立存在的,對每個顯示元素來講,View對象和Controller對象是成對使用的,他們之間並無真正意義的解耦。
  • Controller在這個組合中的角色是處理用戶輸入(例如按鍵和點擊事件),並對這些操做作出符合業務需求的處理。
  • 使用觀察者模式來將Model數據的變動通知View(層,即View+Controller)進行顯示更新。

所以我發現,我設計和使用的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方法以及Objective-C實現

我之因此稱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,以及相關業務邏輯應屬於哪層:

  • Model:領域模型,用於處理和數據相關的操做或業務邏輯,如對數據的增刪改查,與UI層(View和Controller)解耦。
  • Domain-value Object:用於UI層顯示的數據項,隸屬Model層(即在進行數據查詢等操做時由Model層建立),對UI層僅暴露get方法(經過protocol實現),可經過觀察者模式(經過KVO實現)通知UI層數據發生了變動。
  • Controller:處理當前頁面中的用戶交互事件(交互邏輯是什麼),基本等同UIViewController。即Controller負責UI層交互相關的業務邏輯。
  • ModelView:用於特定數據的展現(應該如何顯示)。包括數據處理邏輯(如當name爲空時顯示字符串:未設置),和顯示樣式邏輯(如用戶頭像顯示時採用圓形剪裁或圓角剪裁),並對DO進行監聽,在DO屬性發生變化時更新View。與Controller層解耦,經過觀察者模式與Domain-value Object耦合,能夠與Model層耦合,用於顯示數據的獲取,但不該用於數據修改的提交(即處理用戶交互事件的結果)。
  • View:和業務邏輯徹底無關的可複用的View組件,如UIImageView,與Model和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層中業務邏輯的編寫進行了更爲明確的定義:

  • Controller:用戶輸入事件處理相關業務邏輯
  • ModeView:UI顯示相關業務邏輯
  • View:業務邏輯無關的顯示組件

經過將UI層業務邏輯的分離,爲實現View、Controller、Model三層的開發解耦提供了一種可能性。

相關文章
相關標籤/搜索