您的位置:首页 > 其它

MVP模式分析及简单例子

2017-10-31 16:50 447 查看
一直在用MVC,感觉MVC才是最简单最好用的模式。也一直好奇MVP模式有什么神奇的地方,因为没用过MVP。

最近看了 一个项目中的代码,就是典型的MVP模式,当然有些地方用的还是mvc,比如登录界面,因为逻辑简单,就直接mvc写的。但是一些复杂的页面,功能多,且需要后期维护和业务修改的界面就用的MVP。这里也说些MVP的优势:

1、代码解耦

2、结构清晰

3、可复用、扩展性好

4、方便进行单元测试

再说下mvp的分层思想和每层代表的含义:

主要思想就是将数据层与视图层分开,彻底的分开,即m和v不直接打交道,而是通过一个中介p去联系。相比较mvc的话,mvc的m和v联系的还是比较密的。

MVP

M:就是数据层,主要负责数据的拉取和上传,就是网络请求吧。

V:就是view层,主要负责界面的ui展示

P:就是persenter,主要功能就是将m层请求的数据注入到v层,或者将v层提交的数据传递给m层并回调结果然后控制v层;

p层举个例子:

请求数据:m层主要写网络请求的代码,并通过接口回调结果。p层拿到m层的实例对象调用起请求代码的方法,并实现这个回调接口,这样就拿到数据了,拿到数据后通过v层的实例对象调用v层定义的ui方法,将数据传入,进而实现数据展示。

提交数据:同样也是m层写提交数据的网络代码,比如定义一个方法,传入要提交的参数进行网络操作,并将结果回调给接口。然后p层调用这个方法并实现该接口,那么就拿到这个结果了,拿到这个结果以后调用v的方法,进行其他操作。

而且一般我们都会写一个基类activity,并让这个基类activity为抽象activity,为什么要定义成抽象activity呢?主要是为了定义一个返回p层对象的抽象方法让子类去实现,这样就可以实例化不同需求场景下的不同逻辑控制层p,所以基类activity一般也会添加泛型p,并定义一个T presenter;那么子类activity可以直接用这个presenter调用对应的p层定义的方法。

写个例子:

1、登陆界面

首先我们看M层的代码:

LoginModel.java

public class LoginModel implements ILoginModel{
@Override
public void login(String name,String pwd,ValueCallback<String> callback) {
//登陆操作
//根据用户输入的name和pwd调用登陆接口
//并根据登陆接口返回的结果情况调用
//callback.success(String s);或者callback.onfail(String code)
}
}


M层接口ILogin
4000
Model.java

public interface ILoginModel {

void login(String name,String pwd,ValueCallback<String> s);
}


ValueCallback.java接口,用户将请求到的结果返回

public interface ValueCallback<T> {
void success(T s);
void onfail(String code);
}


LoginModel类就是我们的M层的业务类,它实现了ILoginModel 接口,并实现login方法,里面需要传递用户输入的name和pwd。

再来看V层的代码,前面说过V层主要负责activity中的于view相关的操作。

那么登陆界面我们想一想需要的操作就是用户点击登陆按钮,然后我们将账号和密码拿到然后去调登陆接口是吧。ok,那么我们就定义一个用户点击登陆按钮的方法,和一个登陆请求成功了去首页的方法:

ILoginView.java接口

public interface ILoginView {
void login(String name,String pwd);
void startactivity();
}


V层是给activity去实现的。那么接下来我们看P层怎么去写。

P层:

一般我们都会定义一个Presenter基类,里面写网络请求的方法。因为大多数页面都需要去后台拉数据吧。

那么我们就定义一个BasePresenter吧

BasePresenter.java

public abstract class BasePresenter<T extends BaseActivity> {
//网络请求
public abstract void initData();
}


为什么要加一个baseactivity的泛型呢?是为了指定这个P是对应于哪一个页面,也为了方便之后的维护和检查,一目了然。

BaseActivity.java

public abstract class BaseActivity<T extends BasePresenter> extends Activity {
protected T basepresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayout());
basepresenter = initPresenter();
initView();
}
public abstract void initView();
public abstract  int getLayout();
public abstract T initPresenter();


可以看到baseactivity定义为抽象类,并添加了泛型,为什么要用泛型呢?我讲不出来,为了复用?我的解释是因为我们需要初始化Presenter对象,并且我们需要这个presenter对象为对应的P层的对象。

并添加了3个抽象方法

initview:子类去做一些控件初始化的操作

getLayout:子类需要设置layout布局id

initPresenter:子类返回的对应页面的p层对象

在看对应的逻辑控制层p代码:

LoginPresenter.java

public class LoginPresenter extends BasePresenter<LoginActivity> {
private LoginModel loginModel;
private ILoginView loginView;
public LoginPresenter(ILoginView loginView) {
this.loginView = loginView;
this.loginModel = new LoginModel();
}
@Override
public void initData() {

}
public void loginRequest(String name,String pwd){
loginModel.login(name,pwd,new ValueCallback<String>() {
@Override
public void success(String list) {
loginView.startactivity();
}

@Override
public void onfail(String code) {

}
});
}
}


拿到m和v层的对象,我们看构造方法,m层是直接new的,但是v层是作为参数传递过来的,这也可以反过来解释为什么v层是让activity去实现。initdata不管,这个是通用的请求网络的操作。我们看loginRequest方法,这个方法是我们添加的,供loginactivity中用户点击登陆按钮后调用。是否登陆成功就在success或者onfail方法中了,如果登陆成功了,我们可以继续调用v层的startactivity方法去首页。

然后我们在看子类activity

LoginActivity.java

public class LoginActivity extends BaseActivity<LoginPresenter> implements ILoginView{

@Override
public void initView() {

}

@Override
public int getLayout() {
return 0;
}

@Override
public LoginPresenter initPresenter() {
return new LoginPresenter(this);
}
@Override
public void login(String name,String pwd) {
basepresenter.loginRequest(name,pwd);
}
@Override
public void startactivity() {
//intent打开activity
}
}


这样一个mvp模式的登陆界面的逻辑就完成了。

我们说过mvp模式扩展性好,比如有新需求了,比如添加了注册和忘记密码功能,那么我们只需要在v层添加注册和忘记密码的方法,然后在m层添加对应的网络请求操作,然后在p层添加逻辑控制供activity调用就可以了。

这一套写下来对自己又巩固了一遍,确实感觉mvp模式扩展性很好,复用性高,而且代码解耦做的很好,很清晰,反观自己之前写的代码,真是乱七八糟。但是mvp模式的缺点也体现出来了,就是类多。所以如果逻辑简单的话还是不推荐用mvp,浪费时间不是。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: