Android中Mvp模式
最近一段时间的学习中,用到了MVP设计模式+Retrofit+RxJava加载数据。MVP,说到底是一种设计模式,就像我们之前一直在用的MVC一样。
顾名思义:M--Model层,也就是对应我们的业务逻辑和实体层
V--View层,对应于各个布局文件
C--Cotroller层,对应于Activity
但是在我们平常的开发中,View也就是xml文件中能做得事情非常少,通常数据的加载,数据的绑定,事件的监听等等都是在Activity中完成,这样就造成了Activity既像View,又像Controller。而MVP的出现,加入了一个中间者类Presenter,Presenter负责将View与Model联系在一起,使得Model和View都是与Presenter进行交互,而不能使得View与Model进行交互,这样就实现了程序功能的解耦。使每一层要做的事情更加专一,Activity也就是View层只负责控件的实例化,数据的适配等等操作。MVP中大量的实现都是通过接口的方式,所以MVP的缺点就是类和接口过于冗余,繁多,代码看起来不方便。表现出来的形式就是一个方法跳到另一个方法,一个类跳转到另一个类。下面引用网上的几张图,这是我们的MVC模式:
可以看到,MVC模式下,View的职能不够单一,经常会跟数据打交道,在其中同时要完成加载数据和适配数据。而我们改为MVP模式后:
View每次想要跟数据打交道的时候,都要通过一个Presenter中间者类,这样每一层次的结构和职能就比较清晰了。Model层只负责与数据打交道,得到的数据要适配给谁,数据加载是否成功等都与它无关,只处理加载数据的逻辑(在其中进行Retrofit,OKHttp等等方式加载数据);Presenter层也就是业务逻辑层,负责处理Model与View层之间的通信。负责将Model层获得的数据通过该类中的方法传递给View层(Activity或者是Fragment)中,然后我们在View层中完成数据的适配(ListView等控件的数据的适配)和控件事件的监听。我们一般是在Presenter中回调Model层中的抽象方法,再在model的回调方法中回调View层中的抽象方法。同样的,Model层加载数据需要的参数(比如Url地址中的page页码,分页用到的List集合等等)我们也是通过Presenter传递到Model的具体实现类中。
所以由上分析,总结起来就是:
我们需要在View层中声明一个中间者类对象,通过这个对象我们在View层中调用Presenter中的抽象方法,并且传递Model层加载数据需要的参数等信息。当然,为了调用IView接口中的回调方法,我们还需要实现IView接口,实现其中的方法,在这个方法中得到Model层加载出来的数据。然后再在Presenter中声明Model层对应的对象和View层对应的对象(View层对应的对象应该通过Presenter类的构造函数传递过来,是我们实现IView的Activity或者Fragment,因为我们需要知道调用哪个View的对应的抽象方法)。
数据的传递方向(Model向View):Model层加载数据a---->将数据a传递给Presenter---->在Presenter类中的model对象回调方法中,调用Presenter中传递过来的View对象的相应方法,将数据a通过将a作为该方法参数的形式传递回View,数据a---->View
参数的传递方向(View向Model):View中获得一些参数a(比如EditText的输入等)---->调用Presenter对象的方法,将参数作为该方法的参数传递过去---->在Presenter类中,调用其中声明的Model类对象的方法,将参数a通过回调方法传递过去
我们可以定义几个父接口(基接口):IBaseView,IBaseModel,IBasePresenter(这几个基接口中可以定义我们每个界面都要使用的逻辑方法,比如进度条的显示和取消)。然后在每个需要与数据交互的界面,定义一个XXXContract类,在该类中定义三个接口,分别实现上面的三个基接口,再在基接口中定义我们这个界面需要实现和使用的方法(抽象方法,具体实现逻辑交给其实现类)。之后,再分别定义这三个接口的实现类,在其中完成具体逻辑。这样的话,在每个需要加载数据的界面相当于我们使用四个类来完成数据加载即适配的逻辑,也即XXXContract,XXXModel,XXXActivity,XXXPresenter。
画了一幅不太清楚的Xmind,大家可以看一下,虽然不一定看得明白,画的有点烂。
大体就是这样一个加载过程,不一样的地方可能就是加载数据的时候可以使用RXJava,OKHttp等等自行选择。等这个小项目做完了可能会传到GitHub,到时候会贴出地址,大家也可以去看看~