前言
首先,這篇文章不在講解什麼是mvp模式,如果需要請自行搜索mvp模式文章瞭解.這個文章裏我只記錄mvp模式的創建和mvp各自層的界限.另外這個博客屬於個人使用mvp模式後一些經驗總結與記錄.並不是最好思想的mvp.還有以下總結的mvp都是使用最簡單的mvp模式說明,不是其他大神那種一個類放M/V/P3個內部類(個人不喜歡這種模式),也不是需要各種繼承的mvp模式.
MVP
分別是:
Model
View
Presenter
MVP該從哪裏開始?
思維順序
個人建議書寫順序是,m>v>p.至於爲什麼下面講解:
- M M層需要實現數據的獲取,它的耦合是最低的一個層類,所以放到最前面來書寫,會有很少的停頓.(不必在方法裏調用其他層的東西)
- V V層是負責展現數據的層,它的書寫順序是第二個,爲什麼?因爲它的耦合有,但是也不多.所以放到第二個寫正合適
- P P層是負責組裝數據的層,他有大量耦合,需要大量的調用V的添加數據的方法,和M層獲取數據的方法.所以只有上面2個層完成後,我們才能很順暢的寫出P層,所以理所應當的把P層放到最後來書寫.
實際創建
上面只是說明了書寫順序,當是實際上mvp是6個類(3個接口類,3個實現類)的模塊,所以我們需要了解MVP真正6個類應該以一個怎麼樣的思維分別去按順序創建他們.
- 先將3個MVP的接口類所有需要實現的接口方法全部寫完整.(M層接口類要幹那些網絡獲取數據的方法,V層要幹那些添加數據的方法,P層要幹那些組合和調用M層的方法)
- 以上3個接口類全部書寫完畢後,在分別創建3個MVP層類,接口他們各種的層級,然後在開始按mvp順序實現各個接口方法.
- 當然如果M層是網絡請求,那就需要考慮異步的問題,這個時候還要增加一個接口類負責M層和P層的數據異步(當然這個接口類可以在全部MVP下共用)
MVP各自界限
已開始寫MVP的時候,非常容易把mvp的各種界限搞混,寫着寫着就容易把P層的邏輯寫到V層上,導致P層變成一個銜接反而啥都沒做,這很正常.因爲開發Android App本身在使用MVP開發上會或多或少的有些模糊,跟web端的mvp多多少少有些不同.下面我們就來說一下Android開發mvp的各自界限
M層的界限
1.首先切記M層不能持有任何其他層的實例,因爲它不需要調用其他2個層
2.只書寫需要使用的網絡請求操作(請求網絡/暫停網絡請求/銷燬網絡請求),不寫任何的數據處理邏輯,數據只返回給P層做判斷組裝
3.不攔截處理網絡報錯和異常,所有網絡報錯和異常統統交給上一層P層去判斷
4.在Android裏,建議寫銷燬方法,當然activity被銷燬的時候按層級分別向下銷燬,最終會銷燬M層的網絡請求.否則M的網絡請求不被銷燬會出現報錯問題
接口代碼例子:
public interface DemoModel { void pullDataApi(int id,PDataLinstener linstener);//獲取數據 這裏的PDataLinstener是負責網絡數據異步給上面的P層的接口 void pushDataApi(int id,final PDataLinstener linstener);//提交數據 void stopPullDataApi();//暫停獲取數據 void stopDataPushApi();//暫停提交數據 void destroy();//銷燬 }
P層的界限
1.它持有M層和V層的實例
2.它負責調用View方法導入數據
3.它負責調用M層方法請求網絡
3.負責分類數據或者格式化數據(文本/顏色值/圖片資源id),比如TextView上有一個狀態是同意和拒絕,那麼你在P層就要分類好然後在將文本String調用View方法導入
4.緩存變量數據,個別Activity在銷燬之前都需要緩存一些數據,那麼這些數據交給P層緩存
5.有適配器adapter的activity,適配器應當交給P層創建組裝數據,在分配給ListView或者RecyclerView
6.需要實現銷燬方法,並且在這個銷燬方法裏調用M層的銷燬方法
接口代碼例子:
public interface DemoPresenter { void initView(Activity view);//初始化持有View層 Android的view就是activity,是activity傳入的 void initModel();//初始化持有Model層 void bufferData(int id);//得到Intent傳入的需要緩存的數據 也緩存可以是從M層返回的數據 void pullData(int id);//獲取數據 void pushData(int id);//提交數據 void stopPullData();//暫停獲取數據 void stopPushData();//暫停提交數據 void formatTimeText();//格式化時間文本 void handlerData();//處理獲取後的數據,並且負責調用View方法導入數據 void destroy();//銷燬 }
V層的界限
1.它只能持有P層實例
2.提供所有view的數據導入方法(包括文本/顏色值/圖片資源id等等)
3.它不能處理任何數據邏輯(只能處理是其他activity傳入的數據,獲取後交給P層緩存)
4.不緩存任何數據
5.彈窗對話框可以在V層創建
6.爲了不讓點擊事件太複雜,只要是activity跳轉的點擊事件(activity跳轉還要給調給P層處理是太多餘),讓V層處理.但是如果是網絡請求的點擊事件,點擊後請調用P層的網絡請求方法.
7.可以從持有的P層上獲取緩存數據用於傳出到其他activity
8.在有因爲有多種狀態值,導致一個view需要顯示各種不同的數據的時候(比如根據狀態改變文字顏色或者圖標),這個view可以單獨寫一個方法來導入它的數據.這樣數據分類在P層,但是你始終調用這個方法導入不同的數據
9.只有固定數據的view,可以統一使用一個方法全部導入.
10.需要重寫銷燬方法,將P層的銷燬方法調用
接口代碼例子:
public interface DemoView { void initView(); void initPresenter(); void getIntentData();//獲取activity傳入的數據 void initListener();//初始化監聽 void addStateViewData(String content, @IdRes int textColor);//添加狀態View數據 void addViewData(String view1Content,String view2Content,String view3Content);//添加View的數據 void goneBtn();//隱藏按鍵 void visibleBtn();//顯示按鍵 MaterialDialog pullDataWaitDialog();//獲取數據等待對話框 MaterialDialog pushDataWaitDialog();//提交數據等待對話框 void networkErrorToast();//網絡異常提示 void pushSuccessToast();//提交數據成功提示 }
後話
Android端的整個mvp實現後,m層和v層將會十分簡潔.p層會相對複雜.當你發現你的m層和v層能一眼看明白所有代碼的時候,你的mvp模式差不多就完美了.