每日一題: MVP開發模式

每日一題: MVP開發模式

面試率: ★★★★★

面試提醒

在Android中MVP已經不算是什么新鮮東西了,記得Android以前比較流行的開發模式是MVC,而MVP是MVC的一個擴展,當隨著項目越來越龐大,復雜,參與開發人員越來越多,MVP模式的優勢就充分顯示出來了.

  • 在一個復雜的項目中,不會全部都使用MVP,可能會在某個功能模塊,組件,或者某個頁面中使用.
  • 有時你也會發現一個項目中使用了多種開發模式,這是項目的不斷迭代,業務不斷擴展引起的.

面試技巧

  • MVP模式是MVC模式在Android上的一種變體,要介紹MVP就得先介紹MVC.
    在MVC模式中,Activity應該是屬于View這一層.而實質上,它既承擔了View,同時也包含一些Controller的東西在里面.這對于開發與維護來說不太友好,耦合度大高了.把Activity的View和Controller抽離出來就變成了View和Presenter,這就是MVP模式.
  • MVP雖好,但并不是每個地方都適合去使用,正確的選擇開發模式有利于項目的維護和擴展.
    至少你要了解MVP的優缺點,項目中如何正確使用.

面試題

根據上面問題,我整理了一些相關的問題.

MVP與MVC之間的區別?

  • MVC

View:對應于xml布局文件
Model:實體模型
Controler:對應于Activity業務邏輯,數據處理和UI處理

  • MVP

View:對應于Activity和xml,負責View的繪制以及與用戶交互(接口)
Model:實體模型(也可以是耗時操作)
Presenter:負責完成View于Model間的交互和業務邏輯(中轉器)

在Android開發中MVP的設計思想用得比較多,利用MVP的設計模型可以把部分的邏輯的代碼從Fragment和Activity業務的邏輯移出來,在Presenter中持有View(Activity或者Fragment)的引用,然后在Presenter調用View暴露的接口對視圖進行操作,這樣有利于把視圖操作和業務邏輯分開來.MVP能夠讓Activity成為真正的View而不是View和Control的合體,Activity只做UI相關的事.

MVP優缺點

  • 優點

解耦合:分離了視圖邏輯和業務邏輯,降低了耦合
代碼簡潔:Activity只處理生命周期的任務,代碼變得更加簡潔
可讀性高:視圖邏輯和業務邏輯分別抽象到了View和Presenter的接口中去,提高代碼的可閱讀性
單元測試:Presenter被抽象成接口,可以有多種具體的實現,所以方便進行單元測試
避免OOM:把業務邏輯抽到Presenter中去,避免后臺線程引用著Activity導致Activity的資源無法被系統回收從而引起內存泄露和OOM

  • 缺點

不美觀:Activity需要實現各種跟UI相關的接口,同時要在Activity中編寫大量的事件,然后在事件處理中調用presenter的業務處理方法,View和Presenter只是互相持有引用并互相做回調,代碼不美觀.
邏輯耦合高:這種模式中,程序的主角是UI,通過UI事件的觸發對數據進行處理,更新UI會有線程的問題.而且牽扯到的邏輯耦合度太高,一旦控件更改(如TextView 替換 EditText等)牽扯的更新UI的接口就必須得換.
代碼臃腫:復雜的業務同時會導致Presenter層太大,代碼臃腫的問題.
類變多:類變多了,本來一個Activity就可以完成的功能,現在多了Model,View,Presenter類,對于一些簡單的功能模塊還是用這種開發模式的話會得不償失.

對于MVP的缺點有什么建議或者優化方案?

對于上面部分缺點,我的一些優化方案:

  • 代碼臃腫
    mvp中本身model就是一個實體bean,可有可無,并沒有發揮作用,而一個完整框架應該有三大層(展示層,業務層,數據層)m層相當于數據層.數據層是數據管理者,主要任務就是封裝API,并將數據結果交付給上層.也就是說我們可以將于數據相關的操作封裝在數據層,如網絡請求,網絡狀態判斷,緩存策略等在model中去處理,這樣可以有效的解決Presenter業務過于龐大導致的代碼臃腫問題.

  • 不美觀,邏輯耦合高,類變多
    對這些有問題想進一步優化的,可以考慮使用MVVM開發模式.該模式優點低耦合,UI刷新簡便,使用的類減少,開發效率高,可復用性強,單元測試方便等.

MVP中Presenter在哪里初始化?

Presenter會在UI(Activity,Fragment)中初始化,在這我們可以通過Presenter的引用來調用其內部方法(或者調用Model對象方法)來執行業務,請求回來的數據會在View接口中被回調過來.

MVP中new Presenter(this);這里的this代表什么,是context還是View?

這里的this是MVP中的View接口,因為View接口被UI實現(Activity/Fragment)了所以傳入的并不如context.

單元測試可以在MVP的哪個層里去進行?

MVP中,由于業務邏輯都在Presenter里,我們完全可以寫一個PresenterTest的實現類繼承Presenter的接口,現在只要在Activity里把Presenter的創建換成PresenterTest,就能進行單元測試了,測試完再換回來即可.萬一發現還得進行測試,那就再換成PresenterTest吧.

為什么MVP可以避免Activity內存泄漏?

Android APP 發生OOM的最大原因就是出現內存泄露造成APP的內存不夠用,而造成內存泄露的兩大原因之一就是Activity泄露(Activity Leak)(另一個原因是Bitmap泄露(Bitmap Leak)).

Activity是有生命周期的,用戶隨時可能切換Activity,當APP的內存不夠用的時候,系統會回收處于后臺的Activity的資源以避免OOM.

采用MVP模式,業務操作都在P層處理了,context沒有被關聯進來,因此可以避免因其導致的oom問題.
另外如果presenter層真的要使用到Activitycontext的引用的話
只要在當前的Activity的onDestroy里,分離異步任務對Activity的引用,就能避免 Activity Leak.

為什么采用傳統的MV模式不易解決OOM問題?

采用傳統的MV模式,一大堆異步任務和對UI的操作都放在Activity里面,比如你可能從網絡下載一張圖片,在下載成功的回調里把圖片加載到 Activity 的 ImageView 里面,所以異步任務保留著對Activity的引用.這樣一來,即使Activity已經被切換到后臺(onDestroy已經執行),這些異步任務仍然保留著對Activity實例的引用,所以系統就無法回收這個Activity實例了,結果就是Activity Leak.Android的組件中,Activity對象往往是在堆(Java Heap)里占最多內存的,所以系統會優先回收Activity對象,如果有Activity Leak,APP很容易因為內存不夠而OOM.

舉例說明:遍歷搜索指定sdcard目錄下的圖片集文件夾,并顯示出來?

遍歷文件
線程控制
顯示圖片

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容