Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 設計模式之 淺談MVP

Android 設計模式之 淺談MVP

編輯:關於Android編程

一.概述


MVP(Model-View-Presenter) 是總所周知MVC模式的一個演變,他們的主要目的都是劃分模塊職責,降低模塊耦合,易測試,提高代碼復用,這裡主要針對Android平台來簡單分析MVP.

 

1.層級責任

Model: 負責數據的檢索,持久化等操作

View: 負責UI的繪制和用戶的交互

Presenter: 作為Model和View的中間協調部分,負責兩者之間的業務邏輯處理

 

2.與MVC模式的區別

MVP模式與MVC模式從層級數據流向上來說一個主要的區別應該就是:MVC模式允許View層和Model層直接通訊.從圖1和圖2可以看到MVP和MVC的區別.

圖1MVC模式中Model可以直接update data 到View層。所以當某個View的功能很復雜的時候,View和Model的耦合度可能會很高(並且在android的開發中Activity通常會充當controller&view的角色,結果Activity就很臃腫).而MVP模式就沒有這個問題,View會抽象出來一系列操作UI的接口(Model層也可以),Presenter拿到的都是其他兩個層級的接口來做業務邏輯的處理.這樣不僅可以使View和Model之間的耦合度降低,還可以更易得進行單元測試.

 

\

圖1:MVC模式

 

\

圖2:MVP模式

 

 

3.MVP的優缺點

優點:降低耦合,層級職責更明顯,易於單元測試

缺點:造成類數量爆炸,代碼復雜度和學習成本高,在某些場景下presenter的復用會產生接口冗余

 

 

二. MVP簡單的實例

使用MVP 寫一個簡單的登陸功能,主頁就兩個按鈕:Login 和 Clear

1.項目結構

 

\

 

2.Model層

包含有一個實體UserBean用來承載數據和UserBiz來對登陸數據判斷

 

public class UserBean {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

 

UserBiz通過抽象出一個接口

 

 

public interface UserBiz {
    public void login(UserBean login);
}

UserBizImpl實例化接口,並且通過登陸監聽將結果回調給Presenter

 

 

public class UsrBizImpl implements UserBiz{
    private OnLoginListener listener;

    public UsrBizImpl(OnLoginListener listener){
        this.listener = listener;
    }

    @Override
    public void login(UserBean login) {
        boolean status = false;
        String username,password;
        username = login.getUsername();
        password = login.getPassword();
        if (username != null && "asdf".equals(username))
            if (password != null && "123".equals(password))
                status = true;
        listener.loginStatus(status);
    }
}

3.View層

 

把View層針對控件操作抽象出來一些列的接口

 

public interface LoginView {
    public String getUsername();
    public String getPassword();
    public void clearUsername();
    public void clearPassword();
    public void showMsg(String msg);
}

在Activity裡面實現該接口的控件操作,並且初始化Presenter,這是可以看到Activity裡面沒有邏輯處理,只是對UI的控件進行數據或者行為的操作,所有的動作都是有Presenter的接口來實現,這樣在項目裡面會極大得精簡Activity的體積.

 

 

public class LoginActivity extends Activity implements LoginView{
    private EditText username, password;
    private Button login, clear;
    private LoginPresenter loginPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        init();
    }

    private void init(){
        loginPresenter = new LoginPresenterImpl(this);
        username = (EditText) findViewById(R.id.username);
        password = (EditText) findViewById(R.id.pass);
        login = (Button) findViewById(R.id.login);
        clear = (Button) findViewById(R.id.clear);
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginPresenter.login();
            }
        });

        clear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginPresenter.clear();
            }
        });
    }

    @Override
    public String getUsername() {
        return username.getText().toString();
    }

    @Override
    public String getPassword() {
        return password.getText().toString();
    }

    @Override
    public void clearUsername() {
        username.setText("");
    }

    @Override
    public void clearPassword() {
        password.setText("");
    }

    @Override
    public void showMsg(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    }
}

4.Presenter層

 

在Presenter層裡面,Presenter掌握著View和Model的所有接口,Presenter就可以根據不同的業務邏輯通過MV兩層的接口來實現特定的功能,讓M和V獨立出來.

 

public class LoginPresenterImpl implements LoginPresenter, OnLoginListener{
    private UserBiz userBiz;
    private LoginView loginView;

    public LoginPresenterImpl(LoginView loginView){
        this.loginView = loginView;
        userBiz = new UsrBizImpl(this);
    }

    @Override
    public void login() {
        UserBean login = new UserBean();
        login.setUsername(loginView.getUsername());
        login.setPassword(loginView.getPassword());
        userBiz.login(login);
    }

    @Override
    public void clear() {
        loginView.clearPassword();
        loginView.clearUsername();
    }

    @Override
    public void loginStatus(boolean status) {
        String msg;
        if (status)
            msg = "login succeed";
        else
            msg = "login failed";
        loginView.showMsg(msg);
    }
}

5.Demo下載地址

 

CSDN下載

 

三.總結

簡單得用了下MVP,也有跟朋友討論了一下,好多人都說這個看著挺不錯的,但是用著很麻煩。確實現在Android項目用MVP的不是占多數,帶著一些疑惑樓主就想去了解一下android原生程序裡面是用的什麼風格的,之前也有看過一些android源碼,但是都是斷斷續續的,也好久沒有寫過博客了,本著對技術的熱愛,計劃重新開啟撸android源碼的計劃(從Android原生的系統程序到framework再一路向下),現在希望自己能夠堅持下來,並且產出一個博客的系列和大家一起分享和成長.

 

 

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