Android MVP模式

曾经在一个项目中有一个Activity是负责机票的创单,也就是生成订单的工作,这里的逻辑非常复杂。创单的参数就达到200多个,在创单之前还有许多数据校验以及重复订单的校验操作,如果全部在Activity中实现将会导致代码极其臃肿。
这里我们提供一种解决的思路,就是MVP模式,首先笼统的介绍一下MVP:
我们将Activity复杂的逻辑处理移至另外的一个类(Presenter)中时,Activity其实就是MVP模式中的View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由 Presenter处理)。
MVP的Presenter是框架的控制者,承担了大量的逻辑操作,而MVC的Controller更多时候承担一种转发的作用。因此在App中引入MVP的原因,是为了将此前在Activty中包含的大量逻辑操作放到控制层中,避免Activity的臃肿。
这种模式与MVC的区别:
(最主要区别)View与Model并不直接交互,而是通过与Presenter交互来与Model间接交互。而在MVC中View可以与Model直接交互
通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。而Controller是基于行为的,并且可以被多个View共享,Controller可以负责决定显示哪个View
Presenter与View的交互是通过接口来进行的,更有利于添加单元测试。
下面我们做一下设计:
我们用另一个例子来解释。

先来看包结构图

20140928093820322.png

建立Bean

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;
}
}
建立Model

(处理业务逻辑,这里指数据读写),先写接口,后写实现

public interface IUserModel {
void setID(int id);

 void setFirstName(String firstName);

 void setLastName(String lastName);

 int getID();

 UserBean load(int id);// 通过id读取user信息,返回一个UserBean

}
实现不在这里写了

Presenter控制器

建立presenter(主导器,通过iView和iModel接口操作model和view),activity可以把所有逻辑给presenter处理,这样java逻辑就从手机的activity中分离出来。

public class UserPresenter {
private IUserView mUserView;
private IUserModel mUserModel;

 public UserPresenter(IUserView view) {
        mUserView = view;
        mUserModel = new UserModel();
 }

 public void saveUser( int id, String firstName, String lastName) {
        mUserModel.setID(id);
        mUserModel.setFirstName(firstName);
        mUserModel.setLastName(lastName);
 }

 public void loadUser( int id) {
       UserBean user = mUserModel.load(id);
        mUserView.setFirstName(user.getFirstName()); // 通过调用IUserView的方法来更新显示
        mUserView.setLastName(user.getLastName());
 }

}
View视图

建立view(更新ui中的view状态),这里列出需要操作当前view的方法,也是接口

public interface IUserView {
int getID();

 String getFristName();

 String getLastName();

 void setFirstName(String firstName);

 void setLastName(String lastName);

}
activity中实现iview接口,在其中操作view,实例化一个presenter变量。

public class MainActivity extends Activity implements OnClickListener,IUserView {

 UserPresenter presenter;
 EditText id,first,last;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       setContentView(R.layout. activity_main);

       findViewById(R.id. save).setOnClickListener( this);
       findViewById(R.id. load).setOnClickListener( this);
        id = (EditText) findViewById(R.id. id);
        first = (EditText) findViewById(R.id. first);
        last = (EditText) findViewById(R.id. last);

        presenter = new UserPresenter( this);
 }

 @Override
 public void onClick(View v) {
        switch (v.getId()) {
        case R.id. save:
             presenter.saveUser(getID(), getFristName(), getLastName());
             break;
        case R.id. load:
             presenter.loadUser(getID());
             break;
        default:
             break;
       }
 }

 @Override
 public int getID() {
        return new Integer( id.getText().toString());
 }

 @Override
 public String getFristName() {
        return first.getText().toString();
 }

 @Override
 public String getLastName() {
        return last.getText().toString();
 }

 @Override
 public void setFirstName(String firstName) {
        first.setText(firstName);
 }

 @Override
 public void setLastName(String lastName) {
        last.setText(lastName);
 }

}
因此,Activity及从MVC中的Controller中解放出来了,这会Activity主要做显示View的作用和用户交互。每个Activity可以根据自己显示View的不同实现View视图接口IUserView。

通过对比同一实例的MVC与MVP的代码,可以证实MVP模式的一些优点:

在MVP中,Activity的代码不臃肿;
在MVP中,Model(IUserModel的实现类)的改动不会影响Activity(View),两者也互不干涉,而在MVC中会;
在MVP中,IUserView这个接口可以实现方便地对Presenter的测试;
在MVP中,UserPresenter可以用于多个视图,但是在MVC中的Activity就不行。

你可能感兴趣的:(Android源码解析,android,mvp)