Preface
首先箕慧,感謝一下老師和朋友們對我一直以來的支持以及寬容服球。最近,我所實習(xí)的公司開辦了一個名為 MY Day
的內(nèi)部技術(shù)分享活動颠焦,作為活動的組織者之一及第一期的分享嘉賓斩熊,我倍感榮幸,但同時也壓力山大伐庭》矍考慮到公司新來實習(xí)的同學(xué)們基礎(chǔ)不同,思來想去圾另,第一期還是分享一些基礎(chǔ)的知識霸株,目的是參與的人能夠聽懂,并提出一些比較好的問題集乔,希望起到拋磚引玉的作用去件。內(nèi)容不新鮮,希望大家批評指正扰路,多多包容尤溜,感謝!
What is MVC
MVC全稱是Model View Controller
汗唱,是模型 (model)-視圖 (view)-控制器 (controller) 的縮寫宫莱。它表示的是一種常見的客戶端軟件開發(fā)框架。MVC 的概念最早出現(xiàn)在二十世紀八十年代的 施樂帕克 實驗室中(對渡嚣,就是那個發(fā)明圖形用戶界面和鼠標的實驗室)梢睛,當(dāng)時施樂帕克為 Smalltalk 發(fā)明了這種軟件設(shè)計模式。
現(xiàn)在识椰,MVC 已經(jīng)成為主流的客戶端編程框架绝葡,在 iOS 開發(fā)中,系統(tǒng)為我們實現(xiàn)好了公共的視圖類:UIView
腹鹉,和控制器類:UIViewController
藏畅。大多數(shù)時候,我們都需要繼承這些類來實現(xiàn)我們的程序邏輯功咒,因此愉阎,我們幾乎逃避不開 MVC 這種設(shè)計模式。
How MVC work
總的來說力奋,視圖(view)傳送指令到Controller榜旦,Controller完成業(yè)務(wù)邏輯后,依賴指令去選擇加載某個Model或要求Model改變狀態(tài)景殷,Model將新的數(shù)據(jù)發(fā)送給view溅呢,view更新數(shù)據(jù)澡屡,用戶得到反饋。
- 視圖(View):實現(xiàn)數(shù)據(jù)有目的的顯示咐旧,通常是一個用戶界面元素驶鹉。在視圖中一般沒有程序上的邏輯。在Web應(yīng)用中的MVC铣墨,通常把顯示動態(tài)數(shù)據(jù)的html頁面稱之為視圖骤视。
- 視圖控制器(Controller):處理和響應(yīng)事件金刁,通常是用戶操作试伙,并監(jiān)控模型上的變化兽愤,然后去修改數(shù)據(jù)。
- 模型(Model):模型用于封裝與應(yīng)用業(yè)務(wù)邏輯相關(guān)的數(shù)據(jù)及對相關(guān)數(shù)據(jù)的處理方法碱妆,模型不關(guān)心自己會被如何調(diào)用肉盹、如何顯示昔驱、如何操作疹尾。
How to communicate between M-V-C
該部分圖片及內(nèi)容來自斯坦福大學(xué)公開課,我認為他就 iOS 方面的MVC的通信的描述骤肛,還是比較好的纳本。內(nèi)容概括為以下幾點:
1、Between Controller and View
- Controller通過outlet
"出口"
持有view - View上的action目標動作會反饋到Controller對應(yīng)的target上
- View的沒一個action動作腋颠,都會通過delegate代理反饋給Controller繁成,包括will、did淑玫、should等巾腕,意思是
將要/已經(jīng)/正在
進行動作 - View需要Controller為之解釋模型
- View上需要的數(shù)據(jù),通過View和Controller之間的dataSource數(shù)據(jù)源獲得
- Controller和View之間采用blind structured way(盲結(jié)構(gòu)化方式)通信
2絮蒿、Between Controller and Model
- Controller對Model的訪問完全不受限制尊搬,Model只能被獲取
Model中數(shù)據(jù)的改變,例如數(shù)據(jù)變化土涝、數(shù)據(jù)庫變化或者模型是某種網(wǎng)絡(luò)數(shù)據(jù)庫佛寿,一旦發(fā)生變化,Model通過notification/KVO發(fā)出類似廣播一樣的通知但壮,只有使用到該Model的Controller才會接受該廣播
3冀泻、Between Model and View
- Model完全獨立于View,互相之間一無所知
- iOS開發(fā)中蜡饵,開發(fā)人員最好不要讓View具備接收Model廣播的能力弹渔,因為這可能會違反MVC。
總結(jié)溯祸,在iOS開發(fā)中肢专,我們以一個滾動視圖scrollView
為例巾乳,當(dāng)View開始滾動,View先向Controller詢問鸟召,“我是否可以滾”胆绊,被允許后,視圖開始滾動欧募,并向Controller索要數(shù)據(jù)压状,Controller轉(zhuǎn)向Model獲取數(shù)據(jù),拿到數(shù)據(jù)后跟继,通過dataSource把數(shù)據(jù)交給View顯示种冬。
Advantages and disadvantages
- MVC僅僅是一種設(shè)計模式,MVC的好處在于分離了關(guān)注點舔糖,我們可以最大限度的重復(fù)利用代碼娱两,自動化UI測試也成為可能,大量的代碼被移到單獨的類文件管理金吗。
(所以不要再談MVC能夠為應(yīng)用提高多少性能上的優(yōu)化十兢,也不要讓我通過一個demo的功能演示來描述什么是MVC )
- MVC的缺點是由于它沒有明確的定義,所以完全理解MVC并不是很容易摇庙。使用MVC需要精心的計劃旱物,由于它的內(nèi)部原理比較復(fù)雜,所以需要花費一些時間去思考卫袒。你將不得不花費相當(dāng)可觀的時間去考慮如何將MVC運用到你的應(yīng)用程序宵呛,同時由于模型和視圖要嚴格的分離,這樣也給調(diào)試應(yīng)用程序帶來了一定的困難夕凝。每個構(gòu)件在使用之前都需要經(jīng)過徹底的測試宝穗。一旦你的構(gòu)件經(jīng)過了測試,你就可以毫無顧忌的重用它們了码秉。
- 根據(jù)開發(fā)者經(jīng)驗逮矛,由于開發(fā)者將一個應(yīng)用程序分成了三個部件,所以使用MVC同時也意味著你將要管理比以前更多的文件泡徙,這一點是顯而易見的橱鹏。這樣好像我們的工作量增加了,但是請記住這比起它所能帶給我們的好處是不值一提堪藐。
- MVC并不適合小型甚至中等規(guī)模的應(yīng)用程序莉兰,花費大量時間將MVC應(yīng)用到規(guī)模并不是很大的應(yīng)用程序,通常會得不償失礁竞。
我們對于 MVC 這種設(shè)計模式真的用得好嗎糖荒?其實不是的,MVC 這種分層方式雖然清楚模捂,但是如果使用不當(dāng)捶朵,很可能讓大量代碼都集中在 Controller 之中蜘矢,讓 MVC 模式變成了 Massive View Controller
模式。
Ligher ViewControllers
常見的瘦身方法:
- 將數(shù)據(jù)獲取和轉(zhuǎn)換的邏輯综看,抽取出一個類
- 將拼接空間的邏輯品腹,抽取出一個類
具體抽取哪些邏輯呢?
- 將網(wǎng)絡(luò)請求抽取到單獨的類中:將網(wǎng)絡(luò)請求與具體的第三方依賴庫隔離红碑,方便更換底層的網(wǎng)絡(luò)庫
- 界面的拼裝抽取到專門的類中:將能夠復(fù)用的控件封裝到一個類中舞吭,缺點是需要將控件的時間回調(diào)給Controller
- 專門構(gòu)造存儲類:數(shù)據(jù)的存儲放到專門的類中,方便使用的同時析珊,可以針對存取做額外的事情羡鸥,例如,對一些熱點數(shù)據(jù)進行緩存等操作忠寻、數(shù)據(jù)遷移及切換存儲底層等惧浴。
這里是休息區(qū)~~~比如衷旅,逗逗狗、擼一把...
MVC衍生的MVVM 架構(gòu)
MVVM是Model-View-ViewModel的簡稱祭饭,MVVM模式依賴于數(shù)據(jù)綁定,能自動將對象屬性和UI controls相聯(lián)系是其框架級的特性芜茵。舉個栗子叙量,在微軟的WPF框架里倡蝙,ViewModel將TextField
里的Text屬性和Username屬性綁定,如下所示:
<TextField Text=”{DataBinding Path=Username, Mode=TwoWay}”/>
WPF框架將兩個屬性綁定在一起绞佩。TwoWay綁定確保ViewModel中的Username屬性改變時會為TextField的Text屬性改變做準備,而且可逆.例如用戶輸入時ViewModel的變化寺鸥。另一個例子是著名的基于MVVM的網(wǎng)頁框架Knockout,你可以在動作里看到相似的綁定特性:
<input data-bind=”value: username”/>
上面將HTML元素的一個屬性和JavaScript模型綁定品山。
遺憾的是,iOS缺乏數(shù)據(jù)綁定的框架胆建,但這正是ReactiveCocoa所扮演的角色:進行ViewModel連接"粘合"工作。從iOS開發(fā)的角度來看MVVM模式肘交,ViewController和其相關(guān)的UI(無論是nib笆载、storyboard或者純代碼組成的View)通過ReactiveCocoa將它們綁定在一起。
例如涯呻,我們創(chuàng)建一個ViewModel的新實例凉驻,繼而構(gòu)建和返回View。以下代碼作用為初始化應(yīng)用的navigation controller.
- (UIViewController *)createInitialViewController {
self.viewModel = [RWTFlickrSearchViewModel new];
return [[RWTFlickrSearchViewController alloc] initWithViewModel:self.viewModel];
}
總結(jié)复罐,MVVM是一種設(shè)計架構(gòu)涝登,或者說是一種程序設(shè)計思想。MVVM中將ViewModel與View之間進行雙向數(shù)據(jù)綁定效诅。至于如何實現(xiàn)綁定胀滚,在iOS中采用的是ReactiveCocoa趟济,使View擁有對ViewModel的引用,兩者進行綁定咽笼。使兩者得到同步顷编。另外,ReactiveCocoa 經(jīng)常在ViewModel里來監(jiān)測它本身狀態(tài)來進行其它操作剑刑」葱В【結(jié)束:ReactiveCocoa單獨成章介紹】
【學(xué)習(xí)鏈接】
MVVM與ReactiveCocoa的運用
MVVM Tutorial with ReactiveCocoa