在开发Android应用时,相信不少同窗遇到和我同样的状况,虽然项目刚开始构架时自认为MVC层级分的特别明确,但最终每每是一个Activity有上千行代码,并且业务逻辑和UI的显示混杂在一块儿,致使后续项目的维护成本巨大。设计模式
一个偶然的机会看到有种MVP模式(Mode-View-Presenter)能够比MVC更好地解耦和,而后好奇地研究了下这个模式并尝试在如今项目中进行推广。下面我将本身目前学习到的知识进行一个总结。工具
1.对比MVC与MVP单元测试
我理解的MVP是由MVC优化衍生出来的一种模式,MVP将MVC中的Controller层进行了优化而生成了Presenter。Presenter单词翻译为“提出者/任命者/主持人”,Presenter层和MVC的Controller同样,负责核心逻辑,但不同的是Presenter经过接口协议进行数据传递,并阻断了View和Model的直接联系,从而使View和Model更加专一于自身业务逻辑。学习
● View测试
View一般来讲就是由Activity、Fragment实现的,View会包含一个或多个Presenter的引用来知足视图的业务逻辑。View和Presenter的交互是双向的,即View层能够调用Presenter的逻辑方法,Presenter也能够控制View的显示。优化
● Presenterui
Presenter做为Model和View的桥梁,负责从Model拿到数据进行处理并返回给View。但Presenter和其余两层的沟通是经过接口协议进行的,因此每一个Presenter中一般会包涵一个或多个接口协议。spa
● Model翻译
在MVC里,View是能够直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注Model的不变,而同时有多个对Model的不一样显示,及View。
因此,在MVC模型里,Model不依赖于View,可是 View是依赖于Model的。不只如此,由于有一些业务逻辑在View里实现了,致使要更改View也是比较困难的,至少那些业务逻辑是没法重用的。
2.MVP如何解决MVC的问题
在MVP里,Presenter彻底把Model和View进行了分离,主要的程序逻辑在Presenter里实现。并且,Presenter与具体的View是没有直接关联的,而是经过定义好的接口进行交互,从而使得在变动View时候能够保持Presenter的不变,即重用!
不只如此,咱们还能够编写测试用的View,模拟用户的各类操做,从而实现对Presenter的测试,而不须要使用自动化的测试工具。咱们甚至能够在Model和View都没有完成的时候,就能够经过编写Mock Object(即实现了Model和View的接口,但没有具体的内容的)来测试Presenter的逻辑。
在MVP里,应用程序的逻辑主要在Presenter来实现,其中的View是很薄的一层。所以就有人提出了Presenter First的设计模式,就是根据User Story来首先设计和开发Presenter。在这个过程当中,View是很简单的,可以把信息显示清楚就能够了。在后面,根据须要再随便更改View,而对Presenter没有任何的影响了。
若是要实现的UI比较复杂,并且相关的显示逻辑还跟Model有关系,就能够在View和Presenter之间放置一个Adapter。由这个Adapter来访问Model和View,避免二者之间的关联。而同时,由于Adapter实现了View的接口,从而能够保证与Presenter之间接口的不变。这样就能够保证View和Presenter之间接口的简洁,又不失去UI的灵活性。
在MVP模式里,View只应该有简单的Set/Get的方法,用户输入和设置界面显示的内容,除此就不该该有更多的内容,毫不允许直接访问Model—— 这就是与MVC很大的不一样之处。
3.MVP的优势
◆ 模型与视图彻底分离,咱们能够修改视图而不影响模型;
◆ 能够更高效地使用模型,由于全部的交互都发生在一个地方——Presenter内部;
◆ 咱们能够将一个Presenter用于多个视图,而不须要改变Presenter的逻辑。这个特性很是的有用,由于视图的变化老是比模型的变化频繁;
◆ 若是咱们把逻辑放在Presenter中,那么咱们就能够脱离用户接口来测试这些逻辑(单元测试)。
MVP主要解决的就是把逻辑层抽出来成P层。若是遇到需求业务逻辑上的更改,能够只修改P层,或者遇到逻辑上的大改,也能够直接重写一个P层。不少开发人员把全部的东西都写在了Activity/Fragment里面,这样一来,遇到频繁的需求变动和愈来愈复杂的逻辑时,Activity /Fragment里面就会出现过多的耦合逻辑致使出错。
因此,从控制逻辑和UI的解耦的角度来看,MVP模式是一个不错的选择!