目錄
為什么要談架構
為什么要談架構? 因為很多開發者和產品被架構"傷過"
當然如果你的項目只是1-2個人維護且view不超過20個的"小工程"
你或許沒有意識到的它的存在, 因為只要你嚴格遵守Cocoa MVC你仍然可以寫出不錯的app
鑒于沒人知道業務和產品的發展會是怎樣? 所以在我們"真正"需要架構之前, 架構的第一個原則就是
不要架構, 請嚴格遵守Cocoa MVC
那么今天的討論就到此為止了? 當然不是!
鑒于沒人知道業務和產品的發展會是怎樣? 所以在我們"真正"需要架構之前, 要了解到底有哪些"坑"
架構其實就是一種模式和經驗的最佳實踐, 而這正是移動開發所最缺乏的
鑒于移動開發作為軟件開發細分的"新生力量", 它扔處于高速發展和持續動蕩中, 很多"不算老"的經驗被推翻, 新的偶像被樹立, 因此每個公司每個產品每個開發者開發的方法也都不盡相同, 這些都大大增加了學習和維護的成本, 降低了共享和復用的效率
現實越是殘酷和紛亂, 人們越是需要統一和高效的架構
鑒于業界圈內的一些大拿都有發文討論此問題, 本文不敢造次, 只對已有的設計模式進行一些介紹和討論
有哪些架構模式
今天所討論的架構模式基于MV(X)模式, 主要有以下3種(如果你知道其他的模式和選擇, 歡迎告訴我)
MVC
MVP
MVVM
這三種模式都由如下三個實體組成
Models - 負責主要的數據或者操作數據的數據訪問層
Views - 負責展示層(GUI)
Controller/Presenter/ViewModel - 負責協調Model和View, 通常根據用戶在View上的動作在Model上作出對應的更改, 同時將更改的信息返回到View上
其中MVC又是其他MV(X)的基礎, 所以我們首先就來看看MVC模式
MVC
傳統的MVC
傳統的MVC模式是長這個樣子滴(引自Wiki)
從箭頭的指向可以明顯地看出傳統MVC的缺點
耦合性很強 - 三個實體間相互都有通信
復用性較低
理想的Cocoa MVC
Apple在iOS開發中對傳統MVC進行了改進, "期望"的效果是這樣的
即Controller是一個介于View和Model之間的協調器, 而View和Model之間沒有任何直接的聯系
這個模式解決了傳統MVC部分耦合和復用的問題, 但是當你的邏輯不斷地復雜時
- 很容易就變成了這種MVC(Massive View Controller)
對于這種理想的MVC, 斯坦福大學公開課: iOS 7應用開發有更詳細的說明
實際開發中的Cocoa MVC
雖然理想化的MVC有胖VC的風險, 但已經算是蠻不錯的結構了(胖VC可以轉嫁成胖Model, 并不斷重構和抽象VC中的邏輯)
但是當你真正開發iOS開發時, 你會發現實際的Cocoa MVC并不像人們期望的那樣
怎么回事? View和View Controller被緊緊綁在了一起?! 說好的分離, 說好的解耦, 說好的復用, 一切都是騙人的!
鑒于Cocoa的這種設計, iOS應用架構談 view層的組織和調用方案一文中有這樣一種理解和解釋:
將與ViewController綁定的View理解成ViewContainner, 那么ViewController就還是那個Controller了
但是這樣的理解并不能掩蓋Controller知悉View內部實現而破壞封裝的事實, 如以下寫法所見
var userCell = tableView.dequeueReusableCellWithIdentifier("identifier") as UserCell
userCell.configureWithUser(user)
所以總體來說, 實際開發中的Cocoa MVC并不是嚴格意義上的MVC, 它在實際開發中有如下一些問題
耦合性 - View和Model確實是分開的, 但是View和Controller卻是緊密耦合的
測試性 - 由于只有Model的完全獨立的, 所以只有對Model進行單元測試是相比比較容易的
復用性 - 尤其是View的復用, 這點開發過Android的同學, 都知道xml的復用相比xib或手寫布局強太多
MVP
MVP將MVC中的Controller換成了Presenter, 結構如下
看這個輪廓, 不就是MVC么? 簡單地說, MVP就是理想化的MVC!
那么MVP是如何應用到iOS開發中來的呢? 簡單地說, MVP中就是將MVC中的View Controller當做View!
這樣, MVP就解決了實際開發中Cocoa MVC的幾個缺點, 一切看起來如此地完美? 錯!
增加了代碼量 - 單單增加Presenter就會增加許多新的文件和類, 更何況之前View的delegate從View Controller變成了Presenter
增加了第三方庫接入成本 - 鑒于以往的開發經驗, 第三方UI庫大多是基于Cocoa MVC(注意這里是實際而非理想版)的, 所以如果是用繼承方式接入的話, 會帶來額外成本(至于繼承的優劣, 本文暫不深入討論)
MVVM
鑒于MVP或者說是理想的Cocoa MVC已經是比較完美的結構模式了, 那么為什么還又多出一個MVVM來呢?
因為不管是MVC還是MVP都有一個問題, Controller和Presenter這個"協調員"太關鍵了, 代碼稍微寫多點, 它們就變成了Massive Controller或者Massive Presenter
那么如何給Controller或Presenter減負呢?
答案就是讓View和Model自己去溝通, 讓Controller和Presenter從"協調員"降級成"介紹者"
那么如何理解iOS開發中的MVVM呢? (這次我就當回搬磚的, 引自iOS Architecture Patterns)
So what is the View Model in the iOS reality? It is basically UIKit independent representation of your View and its state. The View Model invokes changes in the Model and updates itself with the updated Model, and since we have a binding between the View and the View Model, the first is updated accordingly.
請注意這里的accordingly, 因為它指出了MVVM最重要的一個特點: 響應式
MVVM幾個熱門的實現都是完全的函數響應式編程
android: ReactiveX/RxJava, square/retrofit
MVVM這么強大, 難道會是"銀彈"不成?
遺憾地說, MVVM也不是"銀彈", 這是因為在實際的移動平臺開發中, 從主流的Objective-C和Java切換至函數響應式思維, 都有不小的學習和培訓成本
鑒于此, ReactiveCocoa或者RxJava應該根據項目的實際情況, 由小到多地逐漸在開發中應用開來, 而不必全盤照搬
小結
討論了這么多, 其實我想說我們的項目還是完完全全的Cocoa MVC
但是了解其他架構模式, 仍是有意義的, 當你知道他們的優缺點, 在面臨新的問題時, 你才能夠從容地做出正確的選擇和判斷
架構的討論遠不止今天這些"皮毛", 歡迎大家一起討論和分享
參考
更多文章, 請支持我的個人博客