在Android开发中,目前常用的设计模式为MVP,MVC。对于MVC大家很了解了。
今天我们从谷歌官方示例来初步讲解一下MVP设计模式。
下图是众所周知的MVP设计模式:
首先分析一下MVP设计模式的优点:
1.Model与View的完全分离,使得我们可以在修改View层或Model层代码时,而互不影响。
2.层次清晰,View负责UI绘制,Presenter负责逻辑处理,Model负责数据处理。
3.方便单元测试,由于逻辑处理全部防止在Presenter层中,单元测试时可以完全脱离Application而直接运行Java代码
4.代码复用性高,处理相同逻辑的Presenter可以用于多个View层。
而在现在,比较传统的MVP分包结构为:
也有简化分包,多层级的:
但是今天我们要讲解的是来自谷歌官方MVP示例《todo-mvp》的分包模式:
可以看到的是除了公用的utils与data之外,示例中的分包全部是以功能来区分
而具体到某一个包内则为:
可以看到的是谷歌并没有分列出Prenseter作为一个单独的包,而是具体的presenter在具体到某个功能分包之中。
而同时也没有看到View与Presenter的接口,但是却多了一个Contract接口类,里面具体的代码是这样的:
可以看到的是其中包含了View与Presenter的接口,虽然并没有看到Model的接口,但是是因为这个示例中并没有使用到网络访问,所以整个代码中都没有涉及Model的东西。实际应用中若有Model层,则也同样应该在这个Contract类中。
针对某一项功能写一个Contract来约束接口,在具体的实现类中实现之后,再次需要调用到同样的功能模块之后,我们只需要在Activity中实现Contract中的接口,或者甚至不需要具体去重新写实现类,而是调用之前写好的实现类,只需要引用接口即可。
谷歌这样做的好处我们来分析一下:
1.传统的MVP设计模式的劣势为包类众多,简单的功能实现可能需要多6个类来实现(View接口及实现类,Presenter接口及实现类,Model接口及实现类),而通过Contract则省去3个接口类,而用一个Contract来代替并统一管理。
A.但是这样做是否就违背了MVP设计模式的Model与View分离呢?
实际上并没有违背,因为实现类是完全分开的,只是使用了一个协议类来管理接口而已。B.那调用多个Presenter是否会非常不方便,显得“为了设计模式而设计模式”呢?
其实也并没有。我们在调用多个Presenter的时候,只需要在Activity中实现View接口,然后运用Java“接口多继承”的特性,让当前功能的View接口继承需要实现的其他View接口,然后在Presenter中就可以正常调用集成类的Presenter。
2.随着需求增多,项目越来越大,传统分包模式会造成各个包十分臃肿。而谷歌官方示例中这样的分包模式则不会。
A.这样做的话,随着项目增大,功能增多,分包也会越来越多,后期不是同样的难以管理吗?
如果以具体到某一个功能的实现来分包确实如此,但是如果以具体到模块来分包,在模块之下才是具体的功能分包,就会非常清晰。也不会导致因为分包而导致难以管理。
比如同样可以这样:B.如果再次细分之后还是觉得很多的话,怎么办呢?
这样的分包模式可以只是一个Application,如果项目大到分包之后再分层级同样还是分包过多的话,则可以使用同样的设计模式去写library,然后用import
Module的形式去调用,这样相互就可以彻底解决分包臃肿的问题。 借用网上的一张图片说明:
3.调用各个功能模块明确,需要查看具体实现代码时更易查找,复用更容易。
A.如果我A里面实现了12,B里面实现了34,我要写一个C需要实现13,那么我岂不是代码复用很困难?
如果遇到这样的问题,则说明功能细分不够明确,面向对象不够理解深刻。正确的做法应该是1234都有具体的实现类,然后A调用12,B调用34,C调用13,而不是12为一个类,34又为另一个实现类。
以上就是我们从谷歌官方示例谈MVP设计模式的全部内容。