Android技术知识Android进阶之路Android知识

对MVP模型的简单理解

2017-04-23  本文已影响290人  安新小子

这里主要是通过看简书上大神的文章和开源项目以后用文字复盘一下自己的理解。笔记早就已经在为知笔记上整理好了,现在发在这里也算是给自己记录一下。

MVP设计模式现在已经算是主流的设计模式了,再不了解真的就out了,我们知道MVP设计模式主要分三方面,M指的是Model层,V指的是View层,P指的是presenter层,那么它们分别具体的起什么作用又怎么用呢?

一:M:model包括两部分,业务逻辑和实体类(即bean类),这里我们只讨论业务逻辑,因为实体类也是为业务逻辑来服务的。
作用:用来获取数据,所有的访问网络获取数据的逻辑都在model包中,对外提供接口暴露获取到的数据,一般使用回调接口来实现数据的暴露
例子:

public class HomeModel {

    //通过回调接口将数据传递出去
    public void loadHomeData(final OnLoadHomeDataListener listener){
        RetrofitManager.getInstance()
                .createApi(HomeApi.class)
                .getHomeData()
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<HomeInfo>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(HomeInfo value) {
                        listener.onSuccess(value);

                    }

                    @Override
                    public void onError(Throwable e) {
                        listener.onFailure(e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

二:V:view,也包括两部分,Activity或者Fragment和对应的View接口。
作用:Activity和Fragment通过对应的View接口拿到数据处理并展示数据

public interface HomeView {
    //显示加载页
    void showProgress();
    //关闭加载页
    void hideProgress();
    //数据加载成功
    void newData(HomeInfo data);
    //显示加载失败
    void showLoadFailMsg();
}

三:P:presenter,负责完成View于Model间的交互 一个正宗的媒婆
作用:通过model层的回调接口拿到数据,调用view层对应的接口将数据传递给view层

也就是说,presenter层只负责调用model层的接口拿到数据,同时只负责调用view层的接口传递给view层,至于数据时怎么获取到的,从哪里获取到的,数据又是怎么处理的,使用什么控件展示的,presenter都不管。

既然我们要在presenter中让view和model进行交互,那么我们就要拿到他们两个的对象,model我们可以直接new出对象,但是view层中的Activity和Fragment我们不能new,同时为了解耦我们要创建与Activity和Fragment对应的接口,只提供页面拿到数据交互的方法
例子:

public class HomePresenter implements OnLoadHomeDataListener<HomeInfo> {

    private HomeView mView;
    private HomeModel mModel;

    public HomePresenter(HomeView view){
        this.mView = view;
        mModel = new HomeModel();
    }

    /**使用Model中的方法加载数据*/
    public void loadData(){
        mModel.loadHomeData(this);
        mView.showProgress();
    }

    @Override
    public void onSuccess(HomeInfo homeInfo) {
        //数据加载工程,隐藏加载页
        mView.newData(homeInfo);
        mView.hideProgress();
    }

    @Override
    public void onFailure(Throwable e) {
        mView.showLoadFailMsg();
    }
}

最后我们还要回到Activity或Fragment,他们要实现对应的View接口,使用控件处理数据

public class HomeFragment extends BaseFragment implements HomeView{


    @Bind(R.id.recycler_view)
    RecyclerView mRecyclerView;
    @Bind(R.id.loading)
    ProgressBar loading;
    @Bind(R.id.net_fail_layout)
    LinearLayout netFail;

    //加载布局文件
    @Override
    protected View initView() {
        View homeView = View.inflate(activity, R.layout.fragment_home, null);
        ButterKnife.bind(this, homeView);
        return homeView;
    }

    //布局加载完毕之后的工作
    @Override
    protected void initData() {
        HomePresenter homePresenter = new HomePresenter(this);
        homePresenter.loadData();
    }

    //显示加载页
    @Override
    public void showProgress() {

    }

    //隐藏加载页
    @Override
    public void hideProgress() {
      
    }

    //加载数据成功
    @Override
    public void newData(HomeInfo data) {
        Log.e("zhang",data.getStories().get(0).getTitle());

    }

    //加载数据失败
    @Override
    public void showLoadFailMsg() {
    
    }
}

这样,MVP的模式就完成了,
好处:1:当我们需要改动界面时,只需要在Activity或者Fragment中改动对应的控件就可以,定位方便同时不影响其他的层
2:一个presenter类可以对应多个视图

欢迎关注我的微信公众号,我会把一些生活的感想和投资方面的总结写到公众号,希望你能来和我一起交流技术之外的东西。

张鹤的公众号
上一篇下一篇

猜你喜欢

热点阅读