如何将既有项目重构成 MVP 模式

开源巨献:Google最热门60款开源项目!很多干货!

吊炸天!74款APP完整源码!

谷歌官方Android应用架构库——LiveData

JavaAndroid架构

欢迎关注我们,一起讨论技术,扫描和长按下方的二维码可快速关注我们。搜索微信公众号:JANiubility。

公众号:JANiubility

最近在做公司项目的重构工作,主要重构点包括:

  • 网络请求框架由 HttpURLConnection + Handler 改为 Retrofit + OkHttp + RxJava

  • 事件通知由 安卓广播 改为 RxBus

  • 图片加载框架由 ImageLoader 改为 Glide

  • 代码优化(瘦身,内存泄漏分析等)

  • 将传统 Activity 作为 God Object 的 MVC 模式 改为兼容原代码的MVP模式

这是现在Android应用的主流架构:

Retrofit + OkHttp + RxJava + MVP

今天主要分享一下,如何将原项目转为MVP模式,并且兼容原有代码。有空的话再分享其他模块的重构经过。

MVP,全称 Model-View-Presenter,其中Presenter解耦了Model与View,使得每个模块的职责更加单一,Model负责获取数据,View只关心视图的绘制,Presenter关联Model和View处理业务逻辑。

与传统的MVC模式相比更加易于维护和排查漏洞,以及更容易编写单元测试。

MVP模式也有一些缺点,比如类文件数目增加,每一层都需要接口与实现类,在系统相对不是特别复杂的情况下可以舍弃Model层与Presenter接口,MVP模式并没用固定的模板,其中每一层的实现可以根据各自的业务场景做相应的调整。

并不是所有的页面都需要使用MVP模式,相对简单的页面完全可以用原来的实现模式。

推荐几篇关于MVP模式介绍比较全面的文章:

Android MVP 详解(上)
http://www.jianshu.com/p/9a6845b26856

Android MVP 详解(下)
http://www.jianshu.com/p/0590f530c617

Google 官方Android MVP架构实践
http://blog.csdn.net/u011459799/article/details/51360882


下面正式开始,如有不妥之处,请老司机多多指教。

首先定义各层的接口,各层之间通过接口耦合:

  1. View接口

public interface IView{ }

2.Model接口:

public interface IModel { }

3.Presenter 接口:

public interface IPresenter<T extends IView> {

   void attachView(T view);
   void start();
   void detachView();  
}

实现一下Ipresenter接口中简单的逻辑:BasePresenter ,使用时直接继承该类:

public abstract class BasePresenter<T extends IView,M extends IModel> implements IPresenter<T> {

   protected static final String TAG = "BasePresenter";
   protected T mView;
   protected M mModel;

   @Override
   public void attachView(T view) {
       mView = view;
   }

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

   public boolean isViewAttached() {
       return mView != null;
   }

   public T getView() {
       return mView;
   }

   public M getModel() {
      return mModel;
   }

}

到目前为止MVP模式的基础代码已经编写完成了,下面的介绍是为了兼容原代码。

现有项目中一般都会有一个BaseActivity,为了方便在Activity中使用MVP模式,以及不影响现有页面,再次实现一个IViewActivity继承BaseActivity封装MVP相关逻辑。如果要使用MVP模式则继承IViewActivity,否则继承BaseActivity,从而兼容了原有代码,并且引入MVP模式开发新页面。

下面是IViewActivity:

/**
* Mvp base activity
* Created by qiulinmin on 16-9-22.
*/

public abstract class IViewActivity<P extends IPresenter> extends BaseActi implements IView {

   protected P mPresenter;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       mPresenter = onLoadPresenter();
       getPresenter().attachView(this);
       initEventAndData();
       if(getPresenter() != null) {
           getPresenter().start();
       }
   }

   public P getPresenter() {
       return mPresenter;
   }

   @Override
   protected void onDestroy() {
       if (getPresenter() != null) {
           getPresenter().detachView();
       }
       super.onDestroy();
   }

   protected abstract P onLoadPresenter();
   protected abstract void initViews(Bundle savedInstanceState);
   protected abstract void initEventAndData();
}

在 onLoadPresenter() 中初始化Presenter,初始化工作完成之后会调用IPresenter.start()方法转到Present层处理业务逻辑。

以上关于MVP模式所有代码都已经编写好了。

使用时为了减少类文件数目,可以写一个Contract接口来统一管理每一层的接口,例如:

public interface DemoContract {

   interface View extends IView {

   }

   interface Model extends IModel {

   }

   interface Presenter extends IPresenter<View> {

   }

}

最后实现present,model接口,

public class DemoPresenter extends BasePresenter<DemoContract.View, DemoContract.Model> implements DemoContract.presenter { }
public class DemoModel implements DemoContract.Model {  }

在DemoPresenter的构造器中需要初始化DemoModel,因为是接口耦合的,在初始化DemoModel时完全可以替换成其他的实现。

最后的最后Activity作为View层实现DemoContract.View:

public class DemoActivity extends IViewActivity<DemoContract.Presenter> implements DemoContract.View {

   protected DemoContract.Presenter onLoadPresenter() {
       return new DemoPresenter();
   }

   protected void initViews(Bundle savedInstanceState) {
       //略...
   }

   protected void initEventAndData() {
       //略...
   }

}

Activity顿时感到如释重负,它只要关心如何绘制UI,把逻辑处理的工作丢给了Presenter,同时存取数据的活交给了Model,Presenter 通过 Model 获取数据,通知 View 绘制界面。而且他们之间又是通过接口耦合的,只要替换掉实现,就能方便的改变需求,Presenter实现中可以不包含任何Android相关的代码,因为是纯Java代码,所以可以方便的使用JUnit配合Mokito进行单元测试

源码及Demo下载关注下方公众号后领取

更多学习资料点击下面二维码关注公众号后领取


Java和Android架构

欢迎关注我们,一起讨论技术,扫描和长按下方的二维码可快速关注我们。搜索微信公众号:JANiubility。

公众号:JANiubility



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值