傳統(tǒng)MVP用在項目中是真的方便還是累贅?

原文地址: http://www.reibang.com/p/ac51c9b88af3
qq群:301733278

前言(最后奉上福利)

自從Google在去年放出MVP官方Sample后,越來越多的人開始加入MVP大軍,MVP可謂在16年大放異彩,我也乘勢推出了我的MVP框架狂刷了一波存在感

問題

但在使用當中我也發(fā)現(xiàn)了諸多弊端,導(dǎo)致很多初學(xué)者,在寫過Sample后,就再也沒在自己的項目中使用過MVP

MVP需要創(chuàng)建太多的類和接口,并且每次通信都需要繁瑣的通過接口傳遞信息

這是大多數(shù)使用過MVP的朋友,最能感受到的,最近在幫公司技術(shù)面,我也時常問應(yīng)聘者,能否嘗試著解決這些問題?

解決方案

其實我之前已經(jīng)有一套解決方案,其實也不能叫解決,只能說是緩解

硬解決

所謂硬解決,便是使用比較暴力的方式,通過Template自動生成需要的類和接口,這樣少去了頻繁的復(fù)制粘貼

軟解決

所謂軟解決,那就要動動腦子,稍微優(yōu)雅的解決了

  1. 對于邏輯簡單的頁面可以不使用Presenter,直接在ActivityFragment中處理邏輯,在Presenter中如果不需要處理數(shù)據(jù),也可以不使用Model

  2. PresenterModel都可以無限制的重用,所以MVP的劃分不需要太細粒度,稍微粗粒度一點,即不需要每個ActivityFragment都給他劃分一套MVP,可以幾個ActivityFragment使用同一個Presenter(使用同一個類不是同一個對象,這個Presenter含有可以共用的邏輯),也可一個ActivityFragment根據(jù)不同的需求持有多個不同類型的Presenter對象,Model層同理,這樣靈活使用,可以在一定程度上緩解MVP類和接口較多的缺點

并沒有完全解決問題

通過上面的解決方案,是可以一定的緩解MVP的缺點,但是并不能完全解決上述缺點

比如想重用Presenter,Presenter就必須只含有公用的邏輯,而實際項目中公用的邏輯并不是那么多,所以能減少的類和接口也是很有限的,如果強制將不同頁面的邏輯放在同一個Prsenter中,來達到重用的目的,那么每個Activity會被迫實現(xiàn)許多并不需要的方法,得不償失

尋求解決方法

因此我看了大多數(shù)MVP框架,尋求如何徹底改善這個問題,像支付寶團隊使用的TheMVP框架,是通過將ActivityFragment作為Presenter,將UI操作抽到Delegate中,作為View

TheMVP優(yōu)點

這樣做的好處是,不僅可以少寫很多類,而且Presenter直接就可以和ActivityFragment的生命周期做綁定 (但使用 Google 最新發(fā)布的 Android 架構(gòu)組件當中的 Lifecycles 就已經(jīng)可以非常簡單的讓任何一個類與 ActivityFragment 的生命周期做綁定, 包括 Presenter, 并且 Support Library v26.1.0 已經(jīng)內(nèi)嵌這個組件, 不用額外的引入這個組件), 且可以隨便重用View(但大多數(shù)場景都是重用Presenter,因為View層變化總是比其它層頻繁)

TheMVP缺點

缺點就是不能重用Presenter,并且對于Presenter的實現(xiàn)有限制,必須是ActivityFragment,如果要在其他地方實現(xiàn)Presenter,如Adapter,Dialog就必須根據(jù)它的特性重新寫對應(yīng)的Presenter基類

因為Presenter基類繼承了ActivityFragment,如果我們需要通過繼承使用其他ActivityFragment,那就又需要修改Presenter基類,一旦某個Activity需要繼承其他不同的Activity,那又需要重新創(chuàng)建一個基于此ActivityPresenter基類,導(dǎo)致一個ActivityFragment有多個不同的Presenter基類

分析問題,解決問題

總結(jié)一下MVP的缺點

1.粒度不好控制,控制不好就需要寫過多的類和接口
2.如要重用presenter可能會實現(xiàn)過多不需要的接口
3.Presenter和View通過接口通信太繁瑣,一旦View層需要的數(shù)據(jù)變化,那么對應(yīng)的接口就需要更改

想要在根本上解決以上問題,我想必須換個思路,能不能通過改變傳統(tǒng)MVP架構(gòu)來解決這些問題?

實現(xiàn)MVP現(xiàn)階段有兩種方式,各有優(yōu)缺點:

一個是將ActivityFragment作為Presenter,抽象一個View層出來

一個是將ActivityFragment作為View,抽象一個Presenter層出來

我想達到重用Presenter的目的,自然選擇了后者

在某一天我突然想到了Handler,他只通過一個handleMessage方法,根據(jù)Messagewhat字段處理不同的操作,這樣向上層提供一個統(tǒng)一的入口,下層不管如何改變并不會影響上層,并且同樣可以實現(xiàn)多種的操作

于是根據(jù)這個思想,我重新改造了MVP架構(gòu),讓Presenter通過MessageView層通信

如何實現(xiàn)

先上張圖

Architecture.png

具體做法是,VIEW層持有Presenter對象,當用戶請求一個事件,則調(diào)用Presenter中的方法,并把持有View引用Message傳給此方法,此方法處理完請求邏輯后將數(shù)據(jù)封裝到Message中,并通過Message持有的View引用回調(diào)ViewhandleMessage方法,讓View做不同的操作,最后釋放掉Message的所有引用,放入消息池

Presenter并不直接持有View,方法執(zhí)行完即表示和View的關(guān)系解除

Handler的原理很像,Handler是將消息放入MessageQueue,Looper去輪循處理消息,我這里是將消息放入,Presenter的方法,并立即處理消息

總結(jié)

這樣就能解決上述的缺點:

  1. 少寫了很多類和接口

  2. 并且Presenter只需要通過handleMessage一個方法與View通信,也就不用繁瑣的一直添加接口方法,只需要一個Message參數(shù),通過Message封裝數(shù)據(jù),即使View需要的數(shù)據(jù)類型發(fā)生改變,也不需要更改任何方法,所以也不會影響上層調(diào)用

  3. 隨便重用Presenter,即使你一個Activity,重用10個不同的Presenter,那也只用實現(xiàn)一個handleMessage方法,不需要實現(xiàn)View中其他用不到的方法,通過一個方法同樣能做到不同的操作(傳統(tǒng)MVP一個頁面對應(yīng)一個Presenter,其實大多數(shù)Presenter只有一兩個方法,這樣導(dǎo)致存在大量代碼寥寥無幾的Presenter,你有想過將相近的邏輯都寫到一個Presenter中,一直重用Presenter有多爽嗎)

  4. Presenter中的方法需要Activity傳遞一些數(shù)據(jù)時,也可以將數(shù)據(jù)封裝到Message中傳給Presenter,這樣即使需要的數(shù)據(jù)類型發(fā)生改變,也不需要更改方法,所以也不會影響上層調(diào)用

只有能不斷的靈活重用,才能感受到MVP的強大之處

當然很多不同的邏輯都寫在一個Presenter中,雖然可以少寫很多類,但是后面的擴展性肯定不好,所以這個粒度需要自己控制,但是對于外包項目簡直是福音

說了這么多還是要看看Demo,具體該怎么做吧蚓胸?

Go!覺得好一定要右上角Star哦!

公眾號

掃碼關(guān)注我的公眾號 JessYan褥民,一起學(xué)習(xí)進步,如果框架有更新向拆,我也會在公眾號上第一時間通知大家

公眾號

Hello 我叫 JessYan烤咧,如果您喜歡我的文章偏陪,可以在以下平臺關(guān)注我

-- The end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市煮嫌,隨后出現(xiàn)的幾起案子笛谦,更是在濱河造成了極大的恐慌,老刑警劉巖昌阿,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饥脑,死亡現(xiàn)場離奇詭異,居然都是意外死亡懦冰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門刷钢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人内地,你說我怎么就攤上這事≮寤海” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵荆针,是天一觀的道長。 經(jīng)常有香客問我航背,道長,這世上最難降的妖魔是什么沃粗? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任粥惧,我火速辦了婚禮,結(jié)果婚禮上最盅,老公的妹妹穿的比我還像新娘突雪。我一直安慰自己起惕,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布咏删。 她就那樣靜靜地躺著惹想,像睡著了一般。 火紅的嫁衣襯著肌膚如雪督函。 梳的紋絲不亂的頭發(fā)上嘀粱,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音辰狡,去河邊找鬼锋叨。 笑死,一個胖子當著我的面吹牛宛篇,可吹牛的內(nèi)容都是我干的娃磺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叫倍,長吁一口氣:“原來是場噩夢啊……” “哼偷卧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吆倦,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤听诸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚕泽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晌梨,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年赛糟,在試婚紗的時候發(fā)現(xiàn)自己被綠了派任。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砸逊。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡璧南,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出师逸,到底是詐尸還是另有隱情司倚,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布篓像,位于F島的核電站动知,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏员辩。R本人自食惡果不足惜盒粮,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望奠滑。 院中可真熱鬧丹皱,春花似錦妒穴、人聲如沸摊崭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘦赫。三九已至蛤迎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝉娜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工召川, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留荧呐,地道東北人纸镊。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像峰搪,于是被迫代替她去往敵國和親凯旭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容