MVP 概念及实现demo

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 {
    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
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(Android,开发,MVP概念,Android开发,设计模式)