MVP模式在android中的流程详解

来源:互联网 发布:北航网络继续教育学院 编辑:程序博客网 时间:2024/06/06 07:02

MVP模式在android中现在已经非常火,相信下面的步骤会为你带来更清晰的编写方式,提高对MVP的理解。

首先为了便于理解,我们先看一下界面:
activity_main示例
我们要实现的功能为:

  • 点击save按钮:把first name和last name存储到数据库内,并绑定到edittext内填写的id上;
  • 点击load按钮:根据edittext内id的值读取数据库中的内容并把数据展示到相应的edittext中。

所以不管是save还是load,edittext_id内必须有值。

具体步骤如下:
1.创建view层的的接口IUserView ,接口内定义跟view内展示的内容有关的相关方法,并让activity实现IUserView ;
ex:

public interface IUserView {    //获取view层activity中edittext中的内容        //由于不管save还是load,edittext_id里的内容都是我们手动输入进去的,所以不需要setID()方法        int getID();        String getFristName();        String getLastName();    //向view层activity中edittext中设置内容        void setFirstName(String firstName);        void setLastName(String lastName);}

2.创建presenter层的类UserPresenter作为连接view层和model层的通道,并创建两个对象:

  1. IUserView 对象,通过构造方法传进,用于把model层的数据显示到实现IView接口的类中(即activity);
  2. IUserModel对象,在构造方法内创建(假如有实现类的话可以通过父类引用指向子类对象的方式创建),用于把view层展示的内容传到model层中,并在实现类中具体实现(如保存、计算、传到服务器等等)。

presenter的代码大概如下 ex:

public class UserPresenter{    private IUserView mUserView;    private IUserModel mUserModel;    public UserPresenter(IUserView view) {        mUserView = view;        mUserModel = new UserModel();//父类引用指向子类对象    }    /**把view层的数据保存到model中(由于是父类引用指向子类对象,所以具体的保存操作可以在UserModel中实现)*/    public void saveUser(int id, String firstName, String lastName) {        mUserModel.setID(id);        mUserModel.setFirstName(firstName);        mUserModel.setLastName(lastName);    }    /**把model层中的数据展示到view层*/    public void loadUser(int id) {        UserBean user = mUserModel.load(id);        mUserView.setFirstName(user.getFirstName());// 通过调用IUserView的方法来更新显示        mUserView.setLastName(user.getLastName());    }}

当然也可以抽象出一个IUserPresenter接口,让UserPresenter实现接口并重写接口中的方法:

//Presenter的接口public interface IUserPresenter{  //5     void saveUser(int id, String firstName, String lastName);    void loadUser(int id) ;}public UserPresenter extend IUserPresenter{    ...}

3、在activity中创建presenter对象,用于连接view层与presenter层(继而连接model层),并在相应的触发事件中调用presenter对象中的方法,完成传输。
ex:

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);//创建presenter对象    }    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.save:            if(id.getText().toString().equals("")){                Toast.makeText(MainActivity.this, "id is not be null", Toast.LENGTH_SHORT).show();                return;            }            presenter.saveUser(getID(), getFristName(), getLastName());//调用保存方法            break;        case R.id.load:            if(id.getText().toString().equals("")){                Toast.makeText(MainActivity.this, "id is not be null", Toast.LENGTH_SHORT).show();                return;            }            presenter.loadUser(getID());//调用展示方法            break;        default:            break;        }    }//以下内容为实现IUserView接口中的方法    @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);    }}

4、编写model层中的接口IUserModel,并定义存储数据的方法和读取数据的方法(具体调用已在第二步presenter的方法中写出),ex:

public interface IUserModel {    //存储数据的三个方法:    void setID(int id);    void setFirstName(String firstName);    void setLastName(String lastName);    //读取数据的方法:    UserBean load(int id);// 通过id读取user信息,返回一个UserBean}

5、编写接口IUserModel的实现类(Impl) UserModel,可具体实现存储到数据库或从数据库中读取等操作,ex:

public class UserModel implements IUserModel {    @Override    public void setID(int id) {        // 存储id到数据库    }    @Override    public void setFirstName(String firstName) {        // 存储firstName到数据库    }    @Override    public void setLastName(String lastName) {        // 存储lastName到数据库    }    @Override    public UserBean load(int id) {        // 查数据库或者联网获取id的userbean        return new UserBean("11", "22");    }}

6、实体类,这一个放到最后一步显然不太合适,但为了可以只把关注点放在view层、presenter层和model层,这里把它剥离出来放到最后写出,ex:

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;    }}

至此,整个mvp模式的简单应用就结束了,可能好多朋友会觉得相比只把这些很简单的功能放在activity内的话代码量可能会减少5倍,使用MVP模式代码量不降反增,而且理解力也不够好了。其实不然,这里只是举了一个很小的例子来说明,真正做项目遇到很复杂的逻辑和页面交互假如都放在activity中显然会写的一团糟,对项目后期维护、单元测试、以及代码理解力来说都会很糟糕,我们充分的把功能解耦,从长远角度来看显然是十分有利的,好了,MVP的基本流程就写到这里,作为自己的一个总结,也希望可以给他人做一份参考。

demo下载地址:http://download.csdn.net/detail/u013325929/9411233

1 0