淺談MVC和MVVM模式


 

MVC

I’m dating with a model… and a view, and a controller.

眾所周知,MVC 是開發客戶端最經典的設計模式,iOS 開發也不例外,但是 MVC 有讓人無法忽視的嚴重問題。

MVC, short for Massive View Controller

在通常的開發中,除了簡單的 Model、View 以外的所有部分都被放在了 Controller 里面。Controller 負責顯示界面、響應用戶的操作、網絡請求以及與 Model 交互。這就導致了 Controller:

  • 邏輯復雜,難以維護。
  • 和 View 緊耦合,無法測試。

 

於是微軟的大牛提出了 MVVM

Model View ViewModel

MVVM

既然 View 和 Controller 是一對好基友,在 MVVM 里面,干脆把它們當做 View。
現在將原來 Controller 的部分職責拆分出來由 View Model 承擔,主要包括:

  • 校驗用戶輸入。
  • 網絡請求。
  • 展示層的邏輯,比如格式化字符串。
  • 其他不能放入 Model,與 View 無關的邏輯。

原來的 Controller 現在只負責綁定 View 和 ViewModel。值得注意的是,View Model 不包含與 View 直接關聯的部分。一般來說,只要代碼中沒有#import <UIKit/UIKit.h>即可。

MVVM 的優點

  • MVVM 兼容 MVC,可以先創建一個簡單的 View Model,再慢慢遷移。
  • MVVM 使得 app 更容易測試,因為 View Model 部分不涉及 UI。

MVVM 最好配合 binding 機制,Model 的變化需要同步到 View Model,View Model 的變化也需要同步到 View。ReactiveCocoa 就可以用來實現 binding,當然它能做的遠遠不止 binding。

Ref

http://www.teehanlax.com/blog/model-view-viewmodel-for-ios/
https://www.objc.io/issues/13-architecture/mvvm/

 

 

之前淺入理解MVC和MVVM

MVC

模型-視圖-控制器(Model-View-Controller

  1. Model和View永遠不能相互通信,只能通過Controller傳遞。
  2. Controller可以直接與Model對話(讀寫調用Model),Model通過Notification和KVO機制與Controller間接通信。
  3. Controller可以直接與View對話,通過outlet,直接操作View,outlet直接對應到View中的控件,View通過action向Controller報告事件的發生(如用戶Touch我了)。Controller是View的直接數據源(數據很可能是Controller從Model中取得並經過加工了)。Controller是View的代理(delegate),以同步View與Controller。

    iOS 中的 MVC

    所謂的 MVC 是指:

    • Model: 數據的擁有者,實現具體的業務邏輯。
    • View: 具體的用戶界面,如按鈕、列表、圖片。
    • Controller: 負責將 View 中用戶的動作傳達給 Model,將 Model 的數據通過 View 展現出來。

    通常 iOS 的每個場景(scene)都由一個 ViewController 來管理,這個 ViewController 可以是庫中原生的,更多情況下是我們自定義的,但是都繼承自 UIViewController。顧名思義,ViewController 包含了 MVC 中的 Controller 和 View,其中的 View 一般是系統提供的 UIButton、UILabel 等類的實例。而 Model 一般都是我們自定義的類。

    MVC 之間的交互

    白胡子老頭的 Keynote

    1.View 與 Controller

    View 與 Controller 的關系是十分緊密的,他們之間可以雙向通信。

    Controller 可以直接操作 View。在使用 Storyboard 進行界面設計時,我們可以直接拖拽現有的控件(View),再通過 Controller—Drag 就可以為各種 控件生成一種類似於句柄的 outlet來作為 ViewController 的屬性,ViewController 通過 outlet 來對 View 進行操作,設置其外觀、狀態或者行為等等。如果是通過純代碼來編寫界面,ViewController 類中就包含了控件的實例,直接通過這些實例的指針進行操作即可。

    View 可以通過特殊的方式來發消息給 Controller。因為系統自定義的 View 並不知道當用戶進行操作之后,Controller 需要做些什么,為了減少耦合性,采用了一些特殊的方式來與 Controller 進行通信。通信的方式有:

    • IBAction。通過 Controller—Drag,XCode 會自動生成事件的響應方法。也可以使用(void)addTarget:(id)target action:(SEL)action方法來注冊事件的響應方法。
    • DataSource。當系統的某些 View 在呈現時需要我們提供相應的數據。我們必須為 View 指定 DataSource,並實現相應的 DataSourceProtocol(所謂的 Protocol 是指預先定義好的一組回調函數,其中的部分是必須實現的,部分是可選的。)最典型的是 UITableView,我們必須告訴系統這個 TableView 有多少行,每行的 Cell 內容是什么。
    • Delegate。它也是一組 Protocol,系統會在特定事件(如網頁的跳轉、網頁加載)發生的前后來調用這些方法。View 可以在不知道某個類的細節的情況下,把該類設置成自己的 Delegate,只要目標類實現了 Protocol 中的必須實現的方法。這些 Protocol 中的方法的命名是有規律的,通常會包含三種關鍵字:
      • will: 表示這個方法會在某種事件發生前調用。
      • did: 表示這個方法會在某種事件發生后調用。
      • should: 通常用來確定該不該讓某件事發生。如webView:shouldStartLoadWithRequest:navigationType:,它的返回值是布爾型,當返回 NO 時,WebView 將不會加載內容。

    2.Model 與 Controller

    Controller 直接向 Model 請求數據。一般將 Model 的類作為 Controller 的屬性,直接調用相應的實例方法或者類方法即可。

    Model 通過 Notification 和 KVO 將數據的變化通知給 Controller。KVO 是指 Key-value observing,是一種觀察者模式的實現,可以使得 Controller 在 Model 的數據變化時能夠得到通知。Notification 是另外一種系統提供的通知機制,與 KVO 的直接通知到觀察者對象不同,系統提供了一個 NotificationCenter 來廣播通知。兩者都可以實現一對一或一對多的關系。

    3.Model 與 View

    他們不能相互發送信息。

 

MVVM

Model -ViewModel - View

什么是 MVVM:一個 MVC 的增強版,我們正式連接了視圖和控制器,並將表示邏輯從 Controller 移出放到一個新的對象里,即 View Model。MVVM 聽起來很復雜,但它本質上就是一個精心優化的 MVC 架構

Model層是少不了的了,我們得有東西充當DTO(數據傳輸對象),當然,用字典也是可以的,編程么,要靈活一些。Model層是比較薄的一層,如果學過Java的小伙伴的話,對JavaBean應該不陌生吧。

ViewModel層,就是View和Model層的粘合劑,他是一個放置用戶輸入驗證邏輯,視圖顯示邏輯,發起網絡請求和其他各種各樣的代碼的極好的地方。說白了,就是把原來ViewController層的業務邏輯和頁面邏輯等剝離出來放到ViewModel層。

View層,就是ViewController層和view,他的任務就是從ViewModel層獲取數據,然后顯示。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM