Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 關於Android MVP模式的思考

關於Android MVP模式的思考

編輯:關於Android編程

最近經常看到各種介紹MVP模式的博客的,之前寫過不少的Android應用,在做那些應用的時候,都是要求快速完成,所以從開始設計到寫代碼就一直考慮著重用。以前寫的項目基本都是不斷重構項目,將項目代碼變得更加精簡,提高代碼之間的復用性。但是代碼並沒有特別地注重按照MVC模式或者是MVP模式來,更多的是直接考慮模塊化,重用,精簡。所以看了MVP模式後,決定去總結一下自己代碼中的問題並優化,算是對自己之前寫的代碼的回顧。

MVP框架

MVP框架是目前在Android流行起來的框架,它非常適合用於Android開發上面。我最早接觸MVP模式是在一本敏捷開發的書上。MVP分別指代M(model),V(View),P(Presenter):
- M(Model):表示數據模型,以及相關的數據結構。
- V(View):表示視圖,主要是指UI界面相關的那些東西。在Android裡面比如說layout的xml文件,在MVP中,很多時候Activity/Fragment也是被看做View。
- P(Presenter):可以直接理解為視圖與模型的中間紐帶。

此處輸入圖片的描述vcq9ysfU9rzT0ru49klNb2RlbL3Tv9q6zUlWaWV3vdO/2qOs08NNb2RlbLrNVmlld7fWsfDKtc/WxMfBvbj2vdO/2qOsUHJlc2VudGVywO/D5rGjtOZJTW9kZWy6zUlWaWV3vdO/2sDg0M21xLPJ1LGx5MG/oaM8L3A+DQo8aDIgaWQ9"代碼示例">代碼示例

下面舉一個關於Android用戶信息的MVP模式例子。

public interface IUserView{
void setName(String name);
}

用戶的JavaBean—User:

class User{
    private String name;
    private String id;
    public String getName(){
        return name;
    }
    public String getId(){
        return id;
    }

    public void setName(String name){
        this.name = name;
    }
    public void setId(String id){
        this.id = id;
    }
}

用戶模型接口

public interface IUserModel{
void saveUser(User user);
User load();
}

真正模型

public class UserModel implements IUserModel{
    void saveUser(User user){
        // 保存用戶信息,保存在本地數據庫中,或者xml裡面
    }
    User loadUser(){
        // 從網絡中,或者從本地緩存中讀取用戶信息
        return null; //未實現
    }
}

Presenter:

public class UserPresenter{
    private IUserView view;
    private IUserModel userModel;
    public UserPresenter(IUserView view){
        this.view = view;
        userModel = new UserModel();
    }
    public void loadUser(){
        // 此處可能是異步load
        User user = userModel.loadUser();
        view.setName(user.getName());
    }
}

把Activity作為View來看待

public class UserActivity extends Activity implements IUserView{
    TextView tvName; //名稱對應的TextView
    UserPresenter userPresenter ;
    public void onCreate(Bundle bundle){
        ...
        userPresenter = new UserPresenter(this);
        // userPresenter.loadUser(); 可以有先初始化
    }

    void setName(String name){
        tvName.setText(name); //如果presenter的loadUser是異步線程,這裡可以通過tvName.post來運行在UI線程。
    }

    void reloadUserData(){ //該函數可以某個按鈕的onClick事件裡面調用
        userPresenter.loadUser(); // 可以是從網絡中加載數據
    }
}

上面代碼中Activity不再與Model直接關聯,而是通過Presenter來間接關聯Model。並且當Model的數據變化了的時候,Presenter能夠通知View。上面的例子是View需要變化了,請求Presenter獲取數據。

分析

MVP與MVC最大的不同就是View和Model不再直接關聯。很多Android的MVC模式都是直接將Activity看作Control,這會導致整個Activity非常臃腫,因為它既然進行UI交互,還需要加上Control這部分的功能。另外即使另外新建一個Control,而把Activity只當做View的功能,如果Activity還是直接跟Model直接關聯的話,因為跟Model直接關聯,還是會在Activity增加很多操作。而使用P作為Model和View的紐帶,P可以先對模型數據進行一些處理,然後再顯示到View。另外一方面對於View的一些請求,Presenter也可以進行一些處理再去請求Model。

上面是關於代碼方面的優勢,其實通過分隔開Model和View,也是將各個模塊進行了解耦。另外一方面通過增加IUserView和IUserModel,這樣每個部分進行單元測試也更加方便了,比如可以直接實現IUserView來模擬測試Presenter。

個人覺得MVP模式適合Android應用,一個很大的原因就是Activity這種組件的存在,UI交互完全放在了Activity裡面,這導致很多時候Activity會在一不注意間就變得臃腫。View過於龐大。當然還有很多跟Android相關的優勢,比如說能夠更好地避免Activity的內存洩漏(Presenter直接引用View,而不是Activity的時候)。其實通過增加Presenter,一定程度上也增加了Presenter的復用,很多人說View和Presenter是一一對應的,但是我覺得如果不一一對應,比如說一個Activity裡面包含多個Presenter,將Presenter細化,那樣Presenter復用的可能性也就越高了,同時也避免了Presenter過於臃腫。

一個模式優化過程

平時自己寫代碼的時候,其實還真的是比較少那麼明顯地使用這種MVP模式,或者說是MVC模式。更多的是模塊化,類層次化(面向對象),面向切面,並且堅持代碼精簡,復用的原則。下面介紹一個將平時的項目簡化後的模式,並且通過考慮優化結構將模式轉變成MVP的過程。先看看下面這種類型結構:
此處輸入圖片的描述

先模塊化將程序分為Fragment/Activity部分,Adapter部分,模型網絡操作部分,通過將相關類進行層次化來減少類的臃腫,另外通過AOP編程的方式將一些內容從子父類中提取出來,作為一個單獨的切面。這種面向切面能夠提高代碼的復用性。

上面的類型圖裡面也有一個不合理的例子,正如上面的注釋中所說的將網絡操作作為模型的一部分,而不是再添加一個接口,會導致網絡操作一旦修改,會影響到Model的子類。

下面看看如何對上面的結構進行轉換。上面這種結構更多的是MVC的方式,而且是將V和C基本合在一起了,內聚在一起能夠更方面UI交互,但是也會導致臃腫。上面的圖中發現只有BaseFragment單向地去關聯Model,這樣勢必會導致Fragment增加更多的代碼來控制,因為在Android中進行網絡連接是一定要在非UI線程操作的,如果Model沒有關連Fragment,必然需要將一個異步操作放到Fragment,等待Model操作完成了後,Fragment來更新Fragment的內容。如果增加一個接口,然後Fragment實現,並且用Model引用它,那麼將能夠減少Fragment的操作,而且能夠更好地去對Model進行單元測試。如果增加一個Presenter,由Presenter與Fragment相互關聯,然後Presenter也與Model相互關聯,那麼Fragment將會大大簡化,更加專注一些其他的UI交互。增加Presenter整個架構就變成了MVP模式了。重構後的類型圖如下:

此處輸入圖片的描述

總結

模式總是堅持著復用,模塊間低耦合,模塊內高內聚等等原則來進行的,設計模式中就有六大原則: 單一職責原則,開閉原則,依賴倒轉原則,迪米特法則,裡氏替換原則,組合聚合原則。好的模式能夠讓人在閱讀的時候能夠很好地理解代碼,在對程序進行修改的時候能夠快速簡潔,並且不對原有代碼結構破壞。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved