Android_I Say No系列——项目框架(一)MVP
还记得刚接触MVP的时候,各种感叹它的神奇,然而自己却不会写,github上找各种可用的开源项目,比如Mosby、TheMvp等优秀框架。然而对于这种老用别人的东东,笔者并不感到满足。首先,如果只是用别人的东东,并不止其所以然,一旦出了Bug基本上项目就要GG,是在给自己挖坑;其二,开源项目一般都包含许多自己用不到的功能,过于臃肿,无故增加项目的体积。
所以,综合种种理由,我们要大声的喊出来,I say no!我要自己写,我要用自己的!
MVP是现在安卓开发中最受欢迎的架构,自从独立开发以来使用MVP架构已经有一年多的时间了。然而对于很多初学者来说MVP的思想还是太绕了,以至于前些天有些朋友还在跟我表示自己不会玩MVP,我当时心里是大写的纳尼......所以赶紧写篇软文交流一下,也给自己机会复习巩固一下。(Windows画图程序手画的图,多多包涵)
目录导读
1、前言:MVP架构的简单介绍;
2、MVP框架搭建:用最少的代码做出MVP的结构;
3、应用:搭建的MVP框架怎么去使用。
前言
说起MVP就不得不说Mvp的前身MVC,MVC的全称是Model-View-Controller,它的结构如下图所示;
MVC的流程是View调用Controller,然后Controller调用Model,再然后Model调用View。但这样有一些问题不好解决:
1、MVC所有的逻辑代码都集中在一个Controller中,臃肿不堪,一个小项目的Controller轻松飙到上千行,不以维护;
2、Model获取数据一般是异步的,而Model却持有View的引用,很多情况下会导致View无法释放,造成Context泄露;
3、......还有其他的问题,这里只是随便列举两条,总之这种环形结构对于安卓是不完美的。
mvc 结构图MVC出现之始目的也是解耦合,在后端和IOS上表现良好,但由于安卓结构的设计(比如既有.java文件又有.xml文件的特点),在安卓上的应用后发现解耦并不是很好,于是MVP应运而生。
MVP的全称是Model-View-Presenter,结构如下图所示(我更愿意画成这样的线性关系,符合它的特点),它所做的就是把MVC的C层给分解成一个个的Presenter减小逻辑层体积,且Model与View不再有直接关系,他们的沟通靠Presenter。
分析一下下图的MVP结构:View与Presenter一一对应并互相持有对方的引用;Presenter持有Model的引用,而反过来Model并不持有Presenter的引用。(实线表示持有引用可以直接调用,虚线表示不持有引用要靠回调);View和Presenter一般情况下是不复用的,而Model却是复用的。
mvp 结构图MVP框架搭建
通过以上的简单分析,我们就来做出一个最基本又最简单的MVP框架。
1、首先,定义View的顶级父接口,用于子类类型的规范,在本例中只是一个空接口,也可以定义一些基本方法。
view 顶级父接口2、然后定义Presenter的顶级父接口,并定义attach和detach方法,这里用到泛型中extends来规定传入的数据类型;
presenter 顶级父接口3、在Presenter中实现刚才接口中定义的attach和detach方法分别用于保存和清除View的引用,当然如果你考虑内存紧张的问题可以考虑使用SoftReference或WeakReference来保持这个View的引用;
presenter 抽象父类4、我们这里用Fragment来展示View层,Activity也是类似这样写。
view 的抽象父类(这里用Fragment做例子,Activity也是类似的操作)这就搭建了一个最基本的基于Fragment的MVP架构,是不是特别简单,你还对MVP望而却步吗,宝宝快写起来吧!
应用:模拟登陆
以上我们搭建了一个极简的MVP框架,现在我们就综合的使用这个框架来真实的体验一下MVP的结构魅力(至今我们还没有见到Model层,其实开发中我一般都是使用Retrofit+Rxjava进行开发,所以Model层都没什么存在感,如果硬要说Model层在哪,那就是使用Retrofit时所定义的那个接口类):
1、首先,定义Login的View和Presenter接口方法.....
Login的View接口 Login的Presenter接口2、这时候View层使用Fragment就继承我们所搭的框架中的BaseMvpFragment,并实现Login的View接口方法,可以清晰的看到,View层只有关于视图的展示代码,逻辑是转而调用Presenter层接口定义的方法;
Login的View实现3、在Presenter中就纯粹是逻辑代码了,试图展示是转而调用View层接口定义的方法:
a、这里是模仿Retrofit+Rxjava,实际使用中还有更多的操作符,如转换map和flatmap、线程切换observeOn和subscribeOn;
Login的Presenter实现b、如果你没有使用Retrofit+Rxjava的组合,那还是需要写Model层的,Presenter和Model参照如下所示(也可以考虑将Model封装成BaseModel加到上面搭建的框架里,在Presenter的detach方法里清除内存占用):
总结:(View和Presenter的接口定义有顺序的,因为泛型需要传入)
说到底MVP是面向接口的编程,使用它的前提重在对它的理解。MVP优点多多,但其实它也是有那么一点缺点的:
优点:结构层次非常清晰、利于维护;
缺点:增加一堆借口,代码量剧增(又不是拿笔写,怕什么呢)......
我在本文里写的MVP是比较简略的,目的是想不要掺入太多的元素,让刚接触MVP的小白们能够更好的理解mvp,刚开始掺多了容易懵圈,这跟走路和跑步的关系是一样的;希望大家学会之后根据自己的需求封装的更多一些功能。