前言
MVP模式是MVC模式的一個演化版本(好像所有的模式都是出自于MVC~~)俊柔,MVP全稱Model-View-Presenter病曾。顧名思義蛋褥,
Model:與MVC中的model沒有太大的區(qū)別。主要提供數(shù)據(jù)的存儲功能橱乱,一般都是用來封裝網(wǎng)絡(luò)獲取的json數(shù)據(jù)的集合郁稍。Presenter通過調(diào)用Model進行對象交互赦政。
View:這里的View與MVC中的V又有一些小差別,這個View可以是viewcontroller耀怜、view等控件恢着。Presenter通過向View傳model數(shù)據(jù)進行交互。
Presenter:作為model和view的中間人财破,從model層獲取數(shù)據(jù)之后傳給view掰派,使得View和model沒有耦合。
說了那么多左痢,總得來說MVP的好處就是解除view與model的耦合靡羡,使得view或model有更強的復用性系洛。
MVP模式下的三個特性的分析
- 任務(wù)均攤 -- 我們將最主要的任務(wù)劃分到 Presenter 和 Model,而 View 的功能較少略步;
- 可測試性 -- 非常好描扯,由于一個功能簡單的 View 層,所以測試大多數(shù)業(yè)務(wù)邏輯也變得簡單趟薄;
- 易用性 -- 代碼量比 MVC 模式的大荆烈,但同時 MVP 的概念卻非常清晰。
iOS MVP 示意圖
- 就 MVP 而言竟趾,UIViewController 的子類實際上就是 Views 并不是 Presenters。這點區(qū)別使得這種模式的可測試性得到了極大的提高宫峦,付出的代價是開發(fā)速度的一些降低岔帽,因為必須要做一些手動的數(shù)據(jù)和事件綁定。
還有一些其他形態(tài)的 MVP -- 監(jiān)控控制器的 MVP导绷。這個變體包含了 View 和 Model 之間的直接綁定犀勒,但是 Presenter 仍然來管理來自 View 的動作事件,同時也能勝任對 View 的更新妥曲。
規(guī)范的MVP設(shè)計模式
Model 層應(yīng)該不僅僅是創(chuàng)建一個數(shù)據(jù)對象贾费,還應(yīng)該包含網(wǎng)絡(luò)請求,以及數(shù)據(jù) SQLite 的 CRUD 操作(比如 iOS 平臺檐盟,一般以 FMDB 框架直接操作 sql褂萧,或者用 CoreData) 。一般可以將數(shù)據(jù)對象是否需要緩存設(shè)計成一個字段 isCache葵萎,或者針對整個項目設(shè)計一個開存儲關(guān)导犹,決定整個項目是否需要數(shù)據(jù)緩存。我們常見的新聞類 App羡忘,在離線的時候看到的數(shù)據(jù)谎痢,都是做了緩存處理的。比如一些金融類的 App卷雕,實時性比較高节猿,是不做緩存的。
View 層比較簡單明了漫雕,就是 View 的一些封裝滨嘱、重用。在一款精心設(shè)計過的 App 里面浸间,應(yīng)該有很多 View 是可以封裝重用的九孩。比如一些自己的 TableViewCell,自己設(shè)計的 Button发框,一些 View(包含一些子 View躺彬,UI 精心設(shè)計過煤墙,在項目里多處出現(xiàn)的)等等。
Presenter 層并不涉及數(shù)據(jù)對象的網(wǎng)絡(luò)請求和 SQLite 操作宪拥,只是 Model 層和 View 層的一個橋梁仿野。Presenter 層就不至于太臃腫,容易看懂她君。一些大的 App脚作,或因為上線時間比較久了,經(jīng)歷過眾多程序員的修補缔刹,或因前期并未做好架構(gòu)球涛,以至于打開一個類,幾千行的代碼校镐,看著自己都暈亿扁。
MVP的優(yōu)勢
- 模型與視圖完全分離,我們可以修改視圖而不影響模型
- 可以更高效地使用模型鸟廓,因為所有的交互都發(fā)生在一個地方——Presenter內(nèi)部
- 我們可以將一個Presener用于多個視圖从祝,而不需要改變Presenter的邏輯。這個特性非常的有用引谜,因為視圖的變化總是比模型的變化頻繁牍陌。
- 如果我們把邏輯放在Presenter中,那么我們就可以脫離用戶接口來測試這些邏輯(單元測試)
MVP的問題
- 由于對視圖的渲染放在了Presenter中员咽,所以視圖和Persenter的交互會過于頻繁.
- 還有一點你需要明白毒涧,如果Presenter過多地渲染了視圖,往往會使得它與特定的視圖的 聯(lián)系過于緊密贝室。一旦視圖需要變更链嘀,那么 Presenter也需要變更了。比如說档玻,原本用來呈現(xiàn)Html的Presenter現(xiàn)在也需要用于呈現(xiàn)Pdf了怀泊,那么視圖很有可能也需要變更。
MVPDemo
參考了http://www.reibang.com/p/abea207c23e7里面給出的一個例子误趴,這里向作者表示感謝霹琼。
先說下例子的核心思想就是:每個模塊會有一個Presenter,Presenter里面包含了View(ViewController)和Model凉当。獲取數(shù)據(jù)(例如網(wǎng)絡(luò)請求等)之后枣申,進行View的展示和ViewController內(nèi)部的邏輯處理。
下面我們結(jié)合代碼來看:
首先來看項目的文件結(jié)構(gòu):
代碼給出了一個控制器作為例子看杭,大家可以看到忠藤,home里面包含了四個文件夾,model楼雹、controller模孩、presenter尖阔、view。home當中的HomePresenter是繼承presenter的榨咐,HomePresenter根據(jù)業(yè)務(wù)的不同來實現(xiàn)自己的presenter介却。
網(wǎng)絡(luò)
網(wǎng)絡(luò)的底層還是用AFNetWorking來實現(xiàn),HttpClient具體的封裝大概為
這里說明一下块茁,這里用delegate而不用block做回調(diào)是因為后面的HomePresenter需要對返回的數(shù)據(jù)進行處理齿坷,為了然后結(jié)構(gòu)更加清晰,遵守一個函數(shù)一個功能的原則数焊。后面還會再說一下永淌。HttpClient提供了賦值responseHandle的init函數(shù),外部可以通過init函數(shù)來綁定responseHandle協(xié)議佩耳。
再來看一下上面那個responseHandle這個proctocol的結(jié)構(gòu):
目前只寫了success和fail兩個回調(diào)遂蛀,這里為了方便演示,只寫了一個參數(shù)蚕愤,這個一塊大伙可以根據(jù)自己的業(yè)務(wù)需求來寫。
結(jié)合HttpClient來看一下饺蚊,我們分別在AFNetWorking請求成功萍诱、失敗的回調(diào)當中處理delegate。簡單說污呼,HttpResponseHandle就是嫁接presenter和HttpClient的協(xié)議~~
接下來看一下父類Presenter的設(shè)計裕坊。先看接口:
這里采用了泛型,簡單說泛型就是有點類似objective-c中的id類型燕酷,大伙可以自行Google一下籍凝。父類Presenter主要是提供綁定View和解綁View的功能。
基于網(wǎng)絡(luò)請求設(shè)計的HttpPresenter苗缩,HttpPresenter繼承與Presenter饵蒂,遵守HttpResponseHandle協(xié)議,并且擁有自己的泛型酱讶,HttpClient成員變量退盯。供外部調(diào)用HttpClient,降低耦合性泻肯。
HttpPresenter.m
應(yīng)用
大致就可以分為這幾層了渊迁,看一下怎么應(yīng)用到實例中。
上文的文件目錄中可以看出我們每個功能模塊都有presenter這個文件夾灶挟,對每個模塊的presenter都是為這個模塊服務(wù)琉朽,我們可以把請求、儲存數(shù)據(jù)的活動放在這里稚铣。并且在這層presenter中處理model數(shù)據(jù)箱叁。為了使controller得到的數(shù)據(jù)能直接使用墅垮,可以多寫一個protocol,來承上啟下蝌蹂,HomeViewProtocol就為了這個產(chǎn)生噩斟。
@protocol HomeViewProtocol
- (void)onGetMovieListSuccess:(HomeModel*)homeModel;
- (void)onGetMovieListFail:(NSInteger) errorCode des:(NSString*)des;
@end
先看了protocol,HomePresenter看起來就清晰多了吧
在看一下controller的調(diào)用孤个,初始化HomePresenter剃允,然后綁定一下自己的視圖,
遵循HomeViewProtocol
結(jié)尾
關(guān)于db這層還沒有寫好齐鲤,大家可以自由發(fā)揮斥废,按照網(wǎng)絡(luò)這種方式,放在業(yè)務(wù)的presenter里面就可以啦给郊,后續(xù)有時間會附上一個基于FMDB的
如果同學們有更好的方案牡肉,隨時歡迎指正~
附上github地址:https://github.com/baoshanf/MVP-iOS
參考
作者:hansfeng
鏈接:http://www.reibang.com/p/abea207c23e7
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)淆九,非商業(yè)轉(zhuǎn)載請注明出處统锤。