MVP 概念及实现demo

来源:互联网 发布:公司网络配置方案 编辑:程序博客网 时间:2024/06/03 09:20

MVP

转载 http://www.jianshu.com/p/fa92ca51bdb0

最近MVP模式很火,可能是因为面向接口编程这种思想逐渐深入人心的缘故。其实MVP的核心就是:将所有的底层接口的功能实现都封装起来,而不让调用者了解到任何实现细节,最终实现用户界面与数据层的高度解耦的一种设计方法。本篇将结合实际的操作来写一写Android MVP模式的实现。

基本概念

M V P 分别代表Model、View、Presenter

  1. View层负责Android界面用户事件和数据展示:一般多为Activity和Fragment;
  2. Model层负责访问数据,如从Server加载的Java Bean、本地的Database、Sharedpreference、文件数据等;
  3. Presenter层是View层与Model层之间数据传输的桥梁;

下图为MVC和MVP模式之间的区别:(其实我们传统的开发模式并不是真正的MVC模式,我认为是一种阉割版的。因为在我们传统编码中Android SDK提供了基于XML的界面框架与存储数据的ContentProvider组件,而开发者则更加专注于业务逻辑的编写。)


MVC-vs-MVP.png

所以我们以往开发模式(MVC)中,如果需要频繁更改显示数据,Activity总是即充当View又充当Controller,那么你的Activity.java文件会出现大量代码,不易于维护和版本迭代。但是当View层和Model层解耦后,就不会出现这种情况。从上图中我们可以看到MVP模式的View层和Model层不发生任何联系,而数据交换与用户操作事件依赖于Presenter层来实现,所以在这一点上,MVP优于传统的编码模式。那么MVP将如何实现呢?

MVP的实现

举一个栗子:网络请求数据,然后显示在用户界面上:
下面的代码的MVP的结构参考这个开源项目,代码结构很清晰。

View层

MvpView

public interface MvpView {    void startLoading();    void hideLoading();    void showError(String msg, View.OnClickListener onClickListener);}

DataView

  public interface DataView extends MvpView {    void loadData(UsBoxEntity usBoxEntity);  }

HotMovieFragment

public class HotMovieFragment extends BaseFragment implements DataView {    @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        presenter = new HotMoviePresenterImpl(getActivity());        presenter.attachView(this);        presenter.loadData();    }    /**      * Presenter 的回调接口,用于更新UI      */      @Override      public void loadData(UsBoxEntity usBoxEntity) {            log.d(usBoxEntity.getTitle());            mAdapter = new OutRecyclerAdapter(getActivity(),usBoxEntity);           recyclerMovie.setAdapter(mAdapter);            //网络请求到的数据在这里更新UI      }}

BaseFragment

public class BaseFragment extends Fragment implements MvpView {    @Override    public void startLoading() {    }     @Override    public void hideLoading() {    }    @Override    public void showError(String msg) {    } }

Presenter层

Presenter

public interface Presenter<V extends MvpView> {    void attachView(V mvpView);    void detachView();}

BasePresenter

public class BasePresenter <T extends MvpView> implements Presenter<T> {    private T mMvpView;    @Override    public void attachView(T mvpView) {        mMvpView = mvpView;    }    @Override    public void detachView() {        mMvpView = null;    }    public boolean isViewAttached() {        return mMvpView != null;    }    public T getMvpView() {        return mMvpView;    }    public void checkViewAttached() {        if (!isViewAttached()) throw new MvpViewNotAttachedException();    }    public static class MvpViewNotAttachedException extends RuntimeException{        public MvpViewNotAttachedException(){            super("Please call Presenter.attachView(MvpView) before requesting data to the Presenter");        }    }}

HotMoviePresenterImpl

public class HotMoviePresenterImpl extends BasePresenter<DataView>{    Context context;    UsBoxEntity usBoxentity;    public HotMoviePresenterImpl(Context context){                this.context = context;    }    @Override    public void attachView(DataView mvpView) {        super.attachView(mvpView);    }    @Override    public void detachView() {         super.detachView();    }    public void loadData(){        //在这里写网络请求的代码,从Server中请求到JavaBena UsBoxEntity        //调用MvpView中的loadData方法,将请求到的数据传回View层,让View层更新数据;         getMvpView().loadData(usBoxentity);    }}

Model层

model层即为网络请求的一些配置(也可以是数据库的请求等),例如:OkHttp、Retrofit等网络请求的配置,由于下一篇将着重讲述Retrofit配合Okhttp的应用,所以这里不详细写。

给出我的Demo的包结构截图供大家参考:


MVP_包结构.png

以上说了很多MVP模式的好,但是并不是说所有的工程都适合MVP。MVP类似于面向接口编程,所以在一个大型项目中会出现很多接口文件,这也是不利于维护的。所以,具体开发还需要根据实际情况选择。



作者:Torang
链接:http://www.jianshu.com/p/fa92ca51bdb0
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原创粉丝点击