MVP简单模型搭建【架构】

作者: 谁动了我的代码 | 来源:发表于2023-02-23 16:23 被阅读0次

    MVP简介

    MVP是一种项目架构设计模式(说白了就是我们产品的一种设计方案) 其实MVP本质 就是将View和Model完全隔离,通过Presenter统一调度管理(Presenter扮演着中介的角色)传统的设计思路是我们直接跟房东谈,效率不高,累。

    • M:Model数据层,一般处理访问网络数据都在这里
    • V:View界面层,与View相关的一些操作都在这里面。View一般代表我们的Activity,Fragment,LinearLayout等等
    • P:Presenter解耦关联层 (关联Model 和 View),可能还要处理一些额外的逻辑操作,数据的处理(比如:数据的筛选等,筛选后给到我们的View去显示)


    优点:

    1.M层和V层完全分离,只需要通过P,V和P层的桥梁,哪个部分出现问题方便修改。只需要找对应的层级就可以  2.适合多人开发, 代码的复用性强

    缺点:

    1.接口回掉多,类的数量增多

    MVP架构搭建流程

    思维构图:

    从0到1搭建MVP架构

    在里面新建两个接口(Interface),分别取名 BaseView 和 BaseModel,这里定义一些公共方法

    public interface BaseView {
        
        void showLoading();
        
        void hideLoading();
        
        void showError();
    
    }
    
    public interface BaseModel {
    
    }
    

    接下来定义一个抽象类,取名 BasePresenter

    public abstract class BasePresenter<M, V> {
    
        protected M mModel;
        //弱引用的写法,避免内存泄漏。
        protected WeakReference<V> mView;
         
        protected void onAttach(M m, V v) {
            mView = new WeakReference<>(v);
            mModel = m;
        }
         
        //检测 V 是否已关联 P
        protected boolean isViewAttached() {
            return null != mView && null != mView.get();
        }
         
        protected V getView() {
            return isViewAttached() ? mView.get() : null;
        }
         
        protected void onDetach() {
            if (null != mView) {
                mView.clear();
                mView = null;
            }
        }
    
    }
    

    该类则用于反射获取指定泛型

    public class ReflectUtil {
    
        public static <T> T getT(Object o, int i) {
            try {
                return ((Class<T>) ((ParameterizedType) (o.getClass().getGenericSuperclass())).getActualTypeArguments()[i]).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    

    接下来定义BaseActivity,举一反三BaseFragment同理

    public abstract class BaseActivity<T extends BasePresenter, M extends BaseModel> extends AppCompatActivity implements BaseView {
    
        protected T mPresenter;
        protected M mModel;
         
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(getLayoutId());
            //通过反射获取presenter model对象
            mPresenter = ReflectUtil.getT(this, 0);
            mModel = ReflectUtil.getT(this, 1);
            //绑定
            mPresenter.onAttach(mModel, this);
         
            initView();
        }
         
        protected abstract int getLayoutId();
         
        protected abstract int initView();
         
        @Override
        public void showLoading() {
         
        }
         
        @Override
        public void hideLoading() {
         
        }
         
        @Override
        public void showError() {
         
        }
         
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //解绑
            mPresenter.onDetach();
        }
    }
    

    创建接口 MvpListener,用于数据从 M 到 V 的层间传递

    public interface MvpListener<T> {
        void onSuccess(T result);
    
        void onError(String errorMsg);
    }
    

    接下来创建一个Contract,来归纳创建view、model、presenter接口,这里可以使用插件mvphelper,省去创建类的步骤

    public interface MainContract {
        interface Model extends BaseModel {
            void loadDaily(String url, MvpListener<String> listener);
        }
    
        interface View extends BaseView {
            void setData(String s);
        }
         
        abstract class Presenter extends BasePresenter<Model, View> {
            abstract void loadData(String url);
        }
    }
    

    然后实现这三层,首先是presenter

    public class MainPresenter extends MainContract.Presenter {
        @Override
        protected void loadData(String url) {
            MainContract.View mView = getView();
            if (mView == null) {
                return;
            }
    
            mView.showLoading();
            //调用model方法,获取网络请求回调结果
            mModel.loadDaily(url, new MvpListener<String>() {
                @Override
                public void onSuccess(String result) {
                    mView.hideLoading();
                    mView.setData(result);
                }
         
                @Override
                public void onError(String errorMsg) {
                    mView.hideLoading();
                    mView.showError();
                }
            });
        }
    }
    

    接下来是model,我这里网络请求使用的okgo,这个根据自己喜好用什么都一样,需要在成功跟失败的回调里去调用自定义的mvplistener

    public class MainModel implements MainContract.Model {
        @Override
        public void loadDaily(String url, MvpListener<String> listener) {
            //这里执行网络请求操作
            OkGo.<String>get(url).execute(new StringCallback() {
                @Override
                public void onSuccess(Response<String> response) {
                    listener.onSuccess(response.body());
                }
    
                @Override
                public void onError(Response<String> response) {
                    super.onError(response);
                    listener.onError(response.body());
                }
            });
        }
    }
    

    最后是view,也就是我们的activity

    public class MainActivity extends BaseActivity<MainPresenter, MainModel> implements MainContract.View {
    
        private static final Locale LOCALE = Locale.CHINA;
         
        @Override
        protected int getLayoutId() {
            return R.layout.activity_main;
        }
         
        @Override
        protected void initView() {
            mPresenter.loadData("http://news.at.zhihu.com/api/4/news/before/" + format(new Date(), "yyyyMMdd"));
        }
    
     
    
        @Override
        public void setData(String s) {
            Toast.makeText(this, "请求结果" + s, Toast.LENGTH_SHORT).show();
        }
         
        public static String format(Date date, String s) {
            return new SimpleDateFormat(s, LOCALE).format(date);
        }
    }
    

    本文意在搭建mvp,就不去做数据列表展示了,在这里做了一个toast,贴上成功的截图


    全文介绍了MVP的介绍及原理;再到0至1的搭建过程;更多架构学习技术,可参考《Android核心技术手册 》点击查看。需要的获取一下。

    总结

    最后,到这里mvp框架就搭建完毕了,总结一下实现过程

    1. 创建baseview、basemodel、basepresenter、baseactivity基类
    2. 创建contract类创建view、model、presenter内部类编写抽象方法
    3. 创建view、model、presenter实现类

    相关文章

      网友评论

        本文标题:MVP简单模型搭建【架构】

        本文链接:https://www.haomeiwen.com/subject/scqtldtx.html