雜談:Android中的MVP設(shè)計(jì)模式

前言

接觸 Android 開發(fā)已有一段時(shí)間带到。

剛開始學(xué)習(xí)時(shí)(大概2017年底)昧碉,每個(gè)星期都會(huì)做一個(gè)小小的項(xiàng)目,類似于商品瀏覽頁面+購物車、本地音樂播放器之類的被饿。那時(shí)候敲代碼只求把功能實(shí)現(xiàn)出來四康,邏輯什么的都寫在 activity/fragment 里,好在項(xiàng)目量級太輕狭握,不會(huì)有什么"代碼不優(yōu)美"的觀感闪金。

2018年寒假待在家的時(shí)候,因?yàn)椴幌胱屪约禾挑~所以打算開發(fā)一個(gè)讓用戶分享語錄的社區(qū)APP论颅。然后什么前期規(guī)劃都沒有毕泌,直接創(chuàng)建項(xiàng)目開始編寫第一個(gè)界面。那個(gè)時(shí)候基本是想到什么新功能就開始查資料嗅辣,然后跟著學(xué)習(xí)、實(shí)踐挠说,所有的業(yè)務(wù)代碼都放在 activity/fragment 里澡谭。隨著功能的不斷擴(kuò)展,每個(gè) activity/fragment 里的代碼也不斷膨脹损俭,加上我是個(gè)不太喜歡注釋的人蛙奖,所以代碼看起來就是亂糟糟的一大堆。不過我當(dāng)時(shí)沒有意識到這個(gè)問題杆兵,感覺能實(shí)現(xiàn)出自己想要的功能就厲害得不行了哈哈哈雁仲。寒假結(jié)束后我的項(xiàng)目也差不多搞完了,之后就放著不管了琐脏。直到大三下學(xué)期的期末需要提交一個(gè)項(xiàng)目攒砖,于是我又把這個(gè)APP的代碼翻出來,打算做一些功能優(yōu)化日裙。結(jié)果一打開代碼我就對自己產(chǎn)生了懷疑吹艇,實(shí)在不想承認(rèn)是自己寫的“悍鳎總體感覺就是代碼很繁冗受神,并且結(jié)構(gòu)不清晰(除了作者之外應(yīng)該沒啥人愿意看),還有很多本可以復(fù)用的邏輯沒有解耦格侯。反正后期的維護(hù)和優(yōu)化都變得十分困難鼻听,也不是難吧,就是要花精力去梳理代碼联四,這點(diǎn)還挺讓人煩躁的撑碴。

隨便放個(gè)當(dāng)初的代碼截圖,感受一下畫風(fēng) (〃-ー-)?


言歸正傳碎连。其實(shí)我上面用的模式都是最傳統(tǒng)的 MVC 吧灰羽。在這個(gè)模式中,Activity 不但承擔(dān)著 View 的角色,還包含了 Controller 的大部分邏輯廉嚼。在項(xiàng)目量級較輕時(shí)玫镐,這樣寫沒有問題。但是項(xiàng)目規(guī)模一旦擴(kuò)大怠噪,Activity 的代碼就會(huì)變得臃腫恐似,且耦合度太高,不利于持續(xù)的開發(fā)與維護(hù)傍念。

MVP 初體驗(yàn)

大四上學(xué)期(2018/11)開始準(zhǔn)備畢設(shè) APP矫夷。因?yàn)檫@時(shí)候已經(jīng)修完幾門關(guān)于"軟件工程生產(chǎn)周期"的課了,也實(shí)習(xí)過一段時(shí)間了(雖然是在寫 JS 和 Python)憋槐,接觸過部門的幾個(gè)項(xiàng)目双藕,所以有了前期準(zhǔn)備的意識。大概就是在編程之前先進(jìn)行背景調(diào)研阳仔、原型設(shè)計(jì)忧陪、架構(gòu)選型、模塊劃分之類的近范。因?yàn)橛辛饲败囍b嘶摊,所以在選擇項(xiàng)目的架構(gòu)模式時(shí),花了好幾天的時(shí)間進(jìn)行仔細(xì)考量评矩,最終敲定了 MVP叶堆。

關(guān)于 MVP 模式,本來打算在這篇博客里詳細(xì)總結(jié)一下斥杜。但是網(wǎng)上講解 MVP 模式的優(yōu)秀文章太多了虱颗,我覺得我既然無法青出于藍(lán),那也就沒有必要花精力寫那么多不痛不癢的內(nèi)容了果录。簡單地畫了兩張UML 圖上枕,談?wù)勎宜斫獾?MVP 模式吧。

定義


MVP 把 Activity 中的 UI 邏輯抽象成 View 接口弱恒,把業(yè)務(wù)邏輯抽象成 Presenter 接口辨萍,Model 類還是原來的 Model。這樣子Activity的工作變得簡單了返弹,只用來響應(yīng)生命周期锈玉,其他工作都丟到Presenter中去完成。從上圖可以看出义起,Presenter 是 Model 和 View 之間的橋梁拉背,為了讓結(jié)構(gòu)變得更加簡單,View 并不能直接對 Model 進(jìn)行操作默终,這也是 MVP 與 MVC 最大的不同之處椅棺。

使用步驟

從上圖中可以看出犁罩,使用MVP,需要經(jīng)歷以下步驟:

  1. 創(chuàng)建 IPresenter 接口两疚,把所有業(yè)務(wù)邏輯的接口都放在這里床估,并創(chuàng)建它的實(shí)現(xiàn) PresenterCompl(在這里可以方便地查看業(yè)務(wù)功能,由于接口可以有多種實(shí)現(xiàn)所以也方便寫單元測試)诱渤。
  2. 創(chuàng)建 IView 接口丐巫,把所有視圖邏輯的接口都放在這里,實(shí)現(xiàn)類是當(dāng)前的 Activity/Fragment勺美。
  3. 由 UML 圖可以看出递胧,Activity 里包含了一個(gè) IPresenter,而 PresenterCompl 里又包含了一個(gè) IView 并且依賴了 Model赡茸。Activity 里只保留對 IPresenter 的調(diào)用缎脾,其它工作全部留到PresenterCompl 中實(shí)現(xiàn)。
  4. Model 并不是必須有的占卧,但是一定會(huì)有 View 和 Presenter赊锚。

總之就是把 Activity 里的許多邏輯都抽離到 View 和 Presenter 接口中去,并由具體的實(shí)現(xiàn)類來完成屉栓。

優(yōu)點(diǎn)

對于初學(xué)者而言,可能無法一下子理解耸袜,沒關(guān)系我之前也是這樣友多,然而動(dòng)手寫了幾個(gè)界面邏輯后立馬就熟悉了。剛開始可能會(huì)覺得文件量驟增堤框,畢竟原來一個(gè) Activity 就能搞定的事域滥,現(xiàn)在我要寫 IView + Activity + IPresenter + PresenterCompl,好煩有沒有蜈抓?不過隨著項(xiàng)目工程的擴(kuò)展启绰,也就漸漸體會(huì)到 MVP 模式的好處了。

優(yōu)點(diǎn)如下:

  1. 分離了視圖邏輯和業(yè)務(wù)邏輯沟使,降低了耦合委可。
  2. Activity只處理生命周期的任務(wù),代碼變得更加簡潔腊嗡。
  3. 視圖邏輯和業(yè)務(wù)邏輯分別抽象到了View和Presenter的接口中去着倾,提高代碼的可閱讀性。
  4. Presenter被抽象成接口燕少,可以有多種具體的實(shí)現(xiàn)卡者,所以方便進(jìn)行單元測試。
  5. 把業(yè)務(wù)邏輯抽到 Presenter 中去客们,避免后臺(tái)線程引用著 Activity 導(dǎo)致 Activity 的資源無法被系統(tǒng)回收從而引起內(nèi)存泄露和OOM崇决。

個(gè)人感受

自從使用了 MVP 模式材诽,腰不疼了腿不酸了,畢設(shè)作品的項(xiàng)目代碼變得更加規(guī)范簡潔恒傻,后期的維護(hù)也方便很多脸侥。入職后接觸的項(xiàng)目代碼也是用的 MVP,于我而言碌冶,少了許多閱讀障礙湿痢。

對于 MVP 的使用,其實(shí)也沒必要按步驟寫的那樣扑庞,必須定義那么多接口譬重。比起學(xué)會(huì)如何使用,更重要的是掌握它的核心思想罐氨,融會(huì)貫通漫雕。無論是 MVC、MVP破衔、MVVM屈糊,事實(shí)上都沒有絕對的孰優(yōu)孰劣,要根據(jù)實(shí)際的項(xiàng)目進(jìn)行考量租悄,有時(shí)候甚至可以多種模式混用(假若有多個(gè)不同業(yè)務(wù)模塊)谨究。總而言之泣棋,具體問題具體分析胶哲。唯一可以確定的是,選擇了適合的架構(gòu)模式潭辈,后期的開發(fā)之路就會(huì)平坦很多鸯屿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市把敢,隨后出現(xiàn)的幾起案子寄摆,更是在濱河造成了極大的恐慌,老刑警劉巖修赞,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件婶恼,死亡現(xiàn)場離奇詭異,居然都是意外死亡柏副,警方通過查閱死者的電腦和手機(jī)熙尉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搓扯,“玉大人检痰,你說我怎么就攤上這事∠峭疲” “怎么了铅歼?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵公壤,是天一觀的道長。 經(jīng)常有香客問我椎椰,道長厦幅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任慨飘,我火速辦了婚禮确憨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瓤的。我一直安慰自己休弃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布圈膏。 她就那樣靜靜地躺著塔猾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稽坤。 梳的紋絲不亂的頭發(fā)上丈甸,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音尿褪,去河邊找鬼睦擂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛杖玲,可吹牛的內(nèi)容都是我干的祈匙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼天揖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了跪帝?” 一聲冷哼從身側(cè)響起今膊,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伞剑,沒想到半個(gè)月后斑唬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡黎泣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年恕刘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抒倚。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡褐着,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出托呕,到底是詐尸還是另有隱情含蓉,我是刑警寧澤频敛,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站馅扣,受9級特大地震影響斟赚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜差油,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一拗军、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蓄喇,春花似錦发侵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至楼眷,卻和暖如春铲汪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背罐柳。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工掌腰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人张吉。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓齿梁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肮蛹。 傳聞我的和親對象是個(gè)殘疾皇子勺择,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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