菜鸡的MVP架构漫谈

作者: markRao | 来源:发表于2018-11-29 16:10 被阅读22次

相信大家在网上看过关于MVP架构的博客数不胜数,至于MVP到底是什么,也不需要我再从百度百科复制一遍了,通俗的说MVP就是解决Model和View的耦合,没有使用架构的代码就是一个Activity里处理了UI逻辑、网络请求等等,有的时候一个Activity五六百行,我曾经看过同事的一个适配器上千行,因为业务逻辑过于复杂,说了这么多,MVP到底有什么作用呢?我们非用不可吗,MVP可以把"功能"抽离出来,因为一个项目中会出现很多页面的某个功能是相似的,这就代表我们不用架构的话,重复的代码会大量的出现在我们的项目中,这不符合单一原则,最后引用一下大佬的总结,“mvp最关键的点就是把Activity中的ui逻辑抽象成view接口,把业务逻辑抽象成presenter接口,model还是数据模型。架构是对客观不足的妥协,规范是对主观不足的妥协。”

public interface IBaseView {
    void showNetError();
    void showDataError();
    void hideLoading();
    void showLoading();
    void showMsg(String msg);
    Activity getMyContext();
}

基类View

public interface IBasePresenter<T> {
    void attachView(T baseView);
    void detachView();
    boolean isViewAttached();
}

基类Presenter

/**
 * Presenter 基类
 * @param <T>
 */
public abstract class BasePresenter<T extends IBaseView> implements IBasePresenter<T> {

    private T view;

    @Override
    public void attachView(T baseView) {
        this.view = baseView;
        initView();
        initModel();
    }
    abstract void initView();
    abstract void initModel();

    @Override
    public void detachView() {
        view = null;
    }

    @Override
    public boolean isViewAttached() {
        return view != null;
    }

    public T getView() {
        return view;
    }
}

抽象基类Presenter

/**
 * Model 回调动作
 * @param <T>
 */
public interface OnCallBackModel<T> {
    /**
     * 请求数据成功时回调动作
     * @param datas
     */
    void onSuccess(T datas);

    /**
     * 数据请求成功,由后台返回的code码非成功码调用动作
     * @param msg
     */
    void onFailure(String msg);

    /**
     * 网络异常
     */
    void onNetError();

    /**
     * 数据异常
     */
    void onDataError();

    /**
     * 网络请求数据完毕后的执行动作,比如隐藏加载动画
     */
    void onComplete();

    /**
     * 网络请求数据之前,比如开启加载动画
     */
    void onBefore();
}

Model的回调接口
以上我自己结合网上博客上的那些MVP博客总结修改的,也是自己在项目中用的,架构比较简单、简陋,但是对于小项目也够用了,也没打算用MVP的开源框架,全自己手写,这里解释下为什么有抽象基类Presenter,因为所有的Presenter都要判断View是否贴上、添加、移除View,这样提取共性比较合适。
在实际的开发过程中,我们可能遇到这种情况,就是一个Activity中需要请求网络判断是否需要更新当前版本和更新用户信息数据,然后另一个Activity也包含了更新用户数据的功能,这样我们就有必要为这个单一的功能抽象出来,那我们怎么在Presenter中去调度呢?

public class AppUpdatePresenter extends BasePresenter<IAppUpdateView> implements IAppUpdatePresenter, IUpdateUserInfoPresenter {

    private IAppUpdateModel model;
    private IUpdateUserInfoModel userInfoModel;
    private IAppUpdateView view;

    @Override
    public void appUpdate(final String version, String type) {
        model.getAppUpdate(version, type, new OnCallBackModel<AppVersionBean>() {
            @Override
            public void onSuccess(AppVersionBean datas) {
                if(isViewAttached()){
                    view.setAppUpdate(datas);
                }
            }

            @Override
            public void onFailure(String msg) {
                if(isViewAttached()){
                    view.showMsg(msg);
                }
            }

            @Override
            public void onNetError() {

            }

            @Override
            public void onDataError() {

            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onBefore() {

            }
        });
    }

    @Override
    public void updateUserInfo(String phone) {
        userInfoModel.getUserInfo(phone);
    }

    @Override
    void initView() {
        view = getView();
    }

    @Override
    void initModel() {
        model = new AppUpdateModel();
        userInfoModel = new UpdateUserInfoModel();
    }
}

最后再贴上Model代码

public class AppUpdateModel implements IAppUpdateModel {
    @Override
    public void getAppUpdate(String version, String type, final OnCallBackModel callBackModel) {
        Map<String, String> params = new HashMap<>(2);
        LogUtils.e("当前版本号------>",  version);
        params.put("version", version);
        params.put("type", type);
        HttpManager.postHttp(ConstantUtils.APP_VERSION, params, new StringCallback() {
            @Override
            public void onError(Call call, Exception e, int id) {

            }

            @Override
            public void onResponse(String response, int id) {
                if(StringUtils.isJSONType(response)){
                    AppVersionBean bean = JsonUtils.fromJson(response, AppVersionBean.class);
                    if(null == bean){
                        callBackModel.onFailure(ConstantUtils.DON_NEED_UPDATE);
                        return;
                    }
                    if(bean.getCode().equals(ConstantUtils.DATA_SUCCESS)){
                        callBackModel.onSuccess(bean);
                    }else {
                        callBackModel.onFailure(ConstantUtils.DON_NEED_UPDATE);
                    }
                }
            }
        });
    }

}
public class UpdateUserInfoModel implements  IUpdateUserInfoModel{
    @Override
    public void getUserInfo(String phone) {
        Map<String, String> params = new HashMap<>(1);
        params.put("mobile", phone);
        HttpManager.postHttp(ConstantUtils.CARD_INFO, params, new StringCallback() {
            @Override
            public void onError(Call call, Exception e, int id) {

            }

            @Override
            public void onResponse(String response, int id) {
                if (StringUtils.isJSONType(response)) {
                    CardInfoBean bean = JsonUtils.fromJson(response, CardInfoBean.class);
                    if (null == bean) {
                        return;
                    }
                    if (null != bean.getData() && bean.getCode().equals(ConstantUtils.DATA_SUCCESS)) {
                        User user = AppUtils.getUserData();
                        CardInfoBean.DataBean datas = bean.getData();
                        user.setReal_name(datas.getReal_name());
                        user.setGender(datas.getGender());
                        user.setPassport_num(datas.getPassport_num());
                        user.setPassport_status(datas.getPassport_status());
                        user.setExpire_time(datas.getExpire_time());
                        user.setId_num(datas.getId_number());
                        AppUtils.updateUserData(user);
                    }
                }
            }
        });
    }
}

最开始我的想法是在更新版本的接口上继承更新用户信息的接口,但是后面想想其实可以实现,但是有一个大问题,违背了单一原则,每一个接口仅仅只负责一个功能,如果需要多个功能,那就新建一个接口多继承所需的功能,切记不可让接口继承接口,接口多继承接口,类多实现接口。

相关文章

  • 菜鸡的MVP架构漫谈

    相信大家在网上看过关于MVP架构的博客数不胜数,至于MVP到底是什么,也不需要我再从百度百科复制一遍了,通俗的说M...

  • 架构文章

    架构漫谈 架构漫谈(一):什么是架构?架构漫谈(二):认识概念是理解架构的基础架构漫谈(三):如何做好架构之识别问...

  • MVC和MVP

    Android mvp 架构的自述 如何更高效的使用MVP以及官方MVP架构解析 老的MVC架构 新的MVP架构 ...

  • Android MVP的简单使用

    1.前言 2.MVC架构 1.MVC架构优缺点 3.MVP架构 1. MVP架构优缺点 四.MVP架构实战 MVP...

  • android MVP架构

    一、MVP介绍 MVP的架构组成如图1所示MVP架构.png相对于MVC架构,MVP架构对应的内容有了如下调整: ...

  • Android主流框架面试准备

    MVP Android MVP架构搭建史上最全的Android MVP模式架构面试题集锦Android面试题-架构...

  • ☆【细品架构4/100】架构之架构切分

    本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(四):如何做好架构之架构切分》的...

  • 【细品架构1/100】架构之缘起

    本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(一):什么是架构?》的心得感受。...

  • 【细品架构2/100】架构之概念认知

    本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(二):认识概念是理解架构的基础》...

  • 【细品架构9/100】技术、业务和架构之间的关系

    本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(九):你理清技术、业务和架构之间...

网友评论

    本文标题:菜鸡的MVP架构漫谈

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