模式是經驗知識的復制應用。MVC設計模式在不同的開發平台有不同闡述和應用。目前在網路上可以搜索出java版本、c++版本、c#版本的,也有ios版本的。我這里也發布這篇關於MVC設計模式的文章,用我的緣走你的路。
寫在前面的話
若然不用設計模式,難道就不能開發設計程序了嗎?不然。那么設計模式給我們帶來什么呢?如果你不學習別人總結出來的設計模式,就能輕松、快捷、真正地解決問題,而且還樂意再來一次,我相信你不需要別人的設計模式了。如果🈶某些問題,讓你很撓頭,讓你不敢再回首,不妨借助別人總結出來的設計模式,來提高一下你的解決方案。
在設計作品中,如果為了使用設計模式而應用設計模式,我認為有點炫技的嫌疑了,大可不必。在iOS APP開發過程中,一般都會涉及到數據處理和UI呈現。如果計算數據的同時還要處理UI的話,會有很多弊端:1. 容易分散精力。2. 不利於復用。3. 重繪畫面的時候容易導致重復計算。為了解決這些弊端,我們需要解耦,MVC設計模式就是對症的葯。
iOS的MVC設計模式
什么是MVC(Model - View - Controller)設計模式?先看下面的圖。(很抱歉,第一次提交后該圖沒有顯示出來。更正之。)

這首先是個分類方面的認識。如,一個程序頁面當中有什么東西呢?容易看出來的有數據內容,比如某些文字描述,某些圖片內容,還有數據相關的呈現方式,如文字的顏色,背景顏色,圖片的大小,位置等。還有別的嗎?恐怕一個靜態的頁面很難勾起這個答案:規則、邏輯、道。這些就是隱藏在程序頁面背后的、數據與呈現方式之間的程序邏輯、決策。
程序頁面包含:
1. 數據
2. 呈現方式
3. 數據與呈現方式之間的關系。
舉個例子,我有四張牌要放到桌面上。要怎樣放?呈扇形排布還是呈一行排布,或者成一列排布?四張牌就是數據;扇形排布就是呈現方式;桌面就是我們的程序頁面。后面這個“怎樣”,就是程序頁面背后隱藏的決策邏輯了。
我們可以把這三者叫三個不同的職責。這三個職責可以應用在不同的思維層面上,比如系統架構上,軟件架構設計上,程序設計上。只要我們從這三個角度來考慮,就是應用了MVC設計模式了。當然在程序代碼層面,iOS的庫中在類的命名和職責上都做的很清楚了,如UITableViewController,UITableView,UITableViewCell,NSArray,NSNumber等。我們也可以在設計自己類時,起個好名字,每個類專注且僅專注於其中一個職責。
MVC設計模式就是這樣思維模式下的一個產物。包含以下內容:
1. Model <=> 數據
2. View <=> 呈現方式
3. 控制器(Controller)<=> 數據與呈現方式之間的關系
4. 以上三者的交互關系。什么關系?
1. Model 不與 View直接通話,如圖中Model和View之間的兩黃實線。
2. Model 與 Controller 通話,如圖中Model和Controller中兩灰色虛實線、當中的綠色箭頭、Model上橙色的KVO。
3. View與 controller 通話,如圖中Controller和View之間兩灰色虛實線、當中的Outlet綠色箭頭、黃色的delegate和data source。
4. View上action 與 controller 上的target。
5. Model上KVO發送端與controller上的黃色接受端。
具體步驟:
第一輪:
設計Model時,先只關注數據所具有的屬性。
設計View時,先只關注任意一個view的呈現方式,不要考慮view中呈現的數據,需要時從controller中可以獲取就行了。
設計Controller時,要關注怎么從Model中獲取數據,要關注怎么通知view,以呈現新的數據。與View的通信可以通過用protocol定義消息,view通過delegate來告訴Controller其事件處理過程中的細節,View通過Data Source來詢問需要呈現的數據。
第二輪:
設計Model時,可以考慮數據來源的多種方式,數據的變化如何通知到Controller,等等。咱主動一點,不能讓Controller拉一下,才動一下。這時,可以加入KVO設計模式或者NSNotification了。這兩者都可以達到這樣的效果:一旦數據(Model)變動,監聽者(這里設為Controller)就收到消息,從而處理該消息。
設計View時,可以考慮如何主動將用戶對數據的操作通知到Controller。如增加手勢處理等。
設計Controller時,可以考慮是否忽略數據的變化對View的影響。若然要考慮變化,則其頻度、緩存等策略又該怎樣呢?
直到第N輪達到該設計可以發布的標准。
例子:我們可以用上面放牌的例子。通過仿照UITableViewController,把每張牌設計類似TableViewCell的類,整個桌面設計成一個類似TableView的類,另外看不到邏輯設計成類似TableViewController的類,每張牌的內容設計成某個繼承於NSObject的類,包含有名字、圖片等屬性。有了這個框架,可以向桌面放任何數目的牌,任何不同的牌,可以按照任一不同的方式排列這些牌,等等。可復用性、可擴展性、低耦合等質量屬性就具備了。如要展示一下的頁面:

閑話完畢。感謝各位讀者,希望能給你帶來靈感。
