(4.6.10)Android中MVP模式与MVC模式比较(含示例)

来源:互联网 发布:小众社交软件 编辑:程序博客网 时间:2024/05/13 01:21

原文链接 http://sparkyuan.me/ 转载请注明出处

MVP

介绍

MVP模式(Model-View-Presenter)是MVC模式的一个衍生。主要目的是为了解耦,使项目易于维护。

  • Model 依然是业务逻辑和实体模型
  • View 经常由Activity实现,包含Presenter的引用。所要做的就是当有交互时,调用Presenter里的对应方法。
  • Presenter 负责完成View于Model间的交互,从Model里取数据,返回给View处理好的数据。

为什么使用MVP

在以往的Android开发中,Activity并不是一个标准的MVC模式中的Controller, 它的加载应用的布局和初始化用户界面,接受并处理来自用户的操作请求,进而作出响应。但是随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。当我们将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理)。 
对于测试来说,在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的。我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。

MVC介绍

  • Model 是应用程序中用于处理应用程序数据逻辑的部分。
  • View 是应用程序中处理数据显示的部分。
  • Controller是应用程序中处理用户交互的部分。 
    具体介绍请戳这里

比较

MVP模式:

  • View不直接与Model交互 ,而是通过与Presenter交互来与Model间接交互
  • Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
  • 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑

MVC模式:

  • View可以与Model直接交互
  • Controller是基于行为的,并且可以被多个View共享
  • 可以负责决定显示哪个View

示例

一个登陆注册的例子。 
示例

目录结构

结构

Model

Model为User的信息,项目里省略了,当然你也可以新建一个User类

public class UserBean {   private String mFirstName ;   private String mLastName ;   public UserBean (String firstName, String lastName) {     this .mFirstName = firstName;     this .mLastName = lastName;   }   public String getFirstName() {     return mFirstName ;   }   public String getLastName() {     return mLastName ;   }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

View

public class LoginActivity extends Activity implements LoginView, View.OnClickListener {  private ProgressBar progressBar;    private EditText username;    private EditText password;    private LoginPresenter presenter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_login);        progressBar = (ProgressBar) findViewById(R.id.progress);        username = (EditText) findViewById(R.id.username);        password = (EditText) findViewById(R.id.password);        findViewById(R.id.button).setOnClickListener(this);        presenter = new LoginPresenterImpl(this);    }    @Override public void onClick(View v) {        presenter.validateCredentials(username.getText().toString(), password.getText().toString());    }    ...    ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

可以看到LoginActivity implements了两个接口,LoginView, View.OnClickListener。LoginView是在Presenter中用来与Activity通信的。在onClick()方法中调用了presenter进行事务处理。

LoginView.java

public interface LoginView {    void showProgress();    void hideProgress();    void setUsernameError();    void setPasswordError();    void navigateToHome();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Presenter

public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {    private LoginView loginView;    private LoginInteractor loginInteractor;    public LoginPresenterImpl(LoginView loginView) {        this.loginView = loginView;        this.loginInteractor = new LoginInteractorImpl();    }    @Override public void validateCredentials(String username, String password) {        if (loginView != null) {            loginView.showProgress();        }        loginInteractor.login(username, password, this);    }    @Override public void onUsernameError() {        if (loginView != null) {            loginView.setUsernameError();            loginView.hideProgress();        }    }    ...    ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

可以发现,在onUsernameError()方法中,把处理好的结果通过LoginView接口返还给Activity进行显示。 
到此为止,整个流程就跑通了,M存储数据,V交互,P处理逻辑。V和P之间通过接口通信。 
示例源码戳这里

原文链接 http://sparkyuan.me/ 转载请注明出处

0 0
原创粉丝点击