浅谈Android中MVP模式用于实际项目中的问题与优化

学习MVP不算久,前段时间才把公司的两个项目完全转换为MVP模式,改了下来,略有心得,给大家分享一下。

才开始学习使用MVP时,看到大家说了很多MVP的优点,代码复用,条理清晰等等。不过我改下来发现,MVP在我看来,最大的优点还是代码解耦,逻辑清晰,至于代码复用,暂时没有感觉很好用,除非是界面和逻辑基本一样的,不然想要复用,其实不太现实。

MVP的优点很明显,缺点其实也很明显,明显项目会多出许多类,增加了项目的复杂程度,而且像某些逻辑及其简单,事件较少的界面,使用MVP实际上反而是累赘,明明用MVC也就几十行代码的事,改成MVP多了好多个类,反而感觉不划算,改需求时又要翻阅好多个类。因此,我建议大家,如果你的某个界面极其简单,其实就不要用MVP了,MVP是逻辑越复杂,优势越明显,逻辑简单时,反而不如MVC好用,希望大家不要为了用MVP而用MVP。

下面来谈谈文章主题,MVP的优化问题,最开始采用网上大家的写法,发现代码的复用性不好,有些逻辑类似的代码,基本上每个presenter 和model都要重新写,于是想到使用Base类的方法,把某些共有的方法抽离以达到代码的复用性,类似于BaseActivity。

举个例子比如网络请求,在MVC中通常是把网络请求封装在BaseActivity中,不过既然是MVP,网络请求自然应该封装在Model里面啦

public abstract class BaseActivityModel implements IPublicModel {
    //网络连接模式,当一个页面含有多个网络请求时,通过传入不同的模式,选择相应的加载参数
    public static final int MODE_ONE=1;
    public static final int MODE_TWO=2;
    public static final int MODE_THREE=3;
    //网络连接工具接口类
    protected InternetConnect mConnect;

    /**  * @param mode 请求模式  * @param intent 上个页面传递过来的intent  * @param i 请求回调  * @param parameter 请求的一些参数  */  @Override
    public void requestData (int mode, Intent intent, JsonI i, String... parameter) {
        HashMap<String, String> map = new HashMap<>();
        JsonBean.Payload payload=new JsonBean.Payload();
        mConnect.loadParameter(intent,mode,payload,map,parameter);//加载参数,由子类实现
        map.put("payload", VolleyConnect.getGson().toJson(payload));
        VolleyConnect.getInVolleyConnect().getServiceMsg( map,i);//封装Volley,传入参数以及回调接口
    }

    /**  * 设置网络请求  */  @Override
    public void setMConnect (InternetConnect mConnect) {
        this.mConnect=mConnect;
    }
}
同样的共有的方法和字段抽象出presenter的基类

public abstract class BaseActivityPresenter<T extends IPublicView, E extends IPublicModel> implements IPublicPresenter {
    protected T view;
    protected E model;
    protected RequestResult mRequestResult;
    protected Handler mHandler;

    public BaseActivityPresenter (T view) {
        this.view = view;
        Type type = getClass().getGenericSuperclass();//使用反射实例化Model
        Type trueType = ((ParameterizedType) type).getActualTypeArguments()[1];
        try {
            this.model = ((Class<E>) trueType).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        new TimeCount(200, 50, new ITimeCount() {
            @Override
            public void isRuning (long millisUntilFinished) {

            }

            @Override
            public void isFinish () {
                init();//加载子类方法,延时200毫秒加载
            }
        }).start();
    }
    /*
    设置网络请求回调
     */
    public void setRequestResult (RequestResult requestResult) {
        mRequestResult = requestResult;
    }
    /*
    获取view的handler,需要传入一个回调接口
     */
    public void setHandler (IHandler handlerI) {
        mHandler = view.exposeHandler(handlerI);
    }

    @Override
    public void requestData (final int mode, String... parameter) {
        view.setLoading(true);
        model.requestData(mode, view.exposeIntent(), new JsonI() {
            @Override
            public void notice (JsonBean bean) {
//                if (bean.getStatus().equals("0")) {
//                    mRequestResult.requestDataSuccess(mode,bean);
//                }else{
//                    mRequestResult.requestDataFail(mode,bean);
//                }
                view.setLoading(false);
            }

            @Override
            public void notice (int error) {
                view.showError(error);
            }
        }, parameter);
    }
}

这样我们就可以更加简单方便的使用MVP模式了,下面是使用示例

public class LoginPresenter extends BaseActivityPresenter<ILoginView,LoginModel> implements ILoginPresenter, RequestResult {
    public LoginPresenter (ILoginView view) {
        super(view);
    }

    @Override
    public void init () {
        setRequestResult(this);
    }

    @Override
    public void requestDataSuccess (int mode, JsonBean bean) {
        
    }

    @Override
    public void requestDataFail (int mode, JsonBean bean) {

    }
}
可以看到,LoginPresenter不再需要去写model字段和网络请求逻辑,通过泛型,可以自动创建model,而网络请求,仅仅需要设置对应的回调就可以哒。

总结,这样做进一步降低了代码耦合,方便以后代码维护,而且整个MVP感觉更加简单。



你可能感兴趣的:(浅谈Android中MVP模式用于实际项目中的问题与优化)