这篇文章主要是对工作两年来用过的架构发表一下自己感触,如果说的不对请轻喷.
关于架构
根据百科中的软件架构,架构描述的对象是直接构成系统的抽象组件,各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象....Android架构目前有许多不同的模式,如MVP, FLUX, MVI, MVVM等.我们当然知道,还用在这bb!!!
挖干的说,决定和实现一个特定的代码体系结构或设计模式都是为了解决我们开发人员时常面对的问题。
一些问题
说到问题我可能有很多要吐槽的了,刚爬进Android这个坑,因为Android本身被写为MVC,所以用的就是MVC模式,那时候只是简单的写一些简单的功能,一个activity处理所有工作,显示View,网络请求,但是毕竟功能简单,一个activity也不会超过百行,所以不会考虑什么耦合,性能问题.对于简单的应用来说,这可能是足够的,但是随着复杂性的增加,问题的数量和水平也会上升。
正式投入Android开发岗位,因为项目前期由一个人完成,所以写的很随意(你懂得),一些业务逻辑稍微复杂的activity或者Fragment超过3000行代码是很正常的,看的时候都不知道从哪开始,每次想要修改点功能都要耗费大量时间看代码逻辑...如果继续这样代码堆砌最后肯定得崩,所以决定采用大家都在口口相传的MVP模式来进行解耦合.当时对于MVP不是很熟,然后一开始的写法是把回调接口写到一个单独的接口中,一个activity对应一个iview,像这种
public class xxPresenter implements xxContract.Presenter {
activity或者Fragment实现contract中的view的方法,
public class xxFragment implements xxContract.View {
这样确实做到了view和逻辑的解耦.
愉快的开发了一段时间后,发现每当我有两个功能相近的页面,而且还要同样的一个请求方法,于是想复用一个contract中的presenter中方法,然后就会造成在某个页面的中会有多余的空方法,而且还不能删除,
这就是使用的mvp的历程,代码的紧密耦合,即使是代码中的一小部分的更改,也会导致代码的其他部分的更改或者引起错误。减少了可重用性,最终导致代码复制粘贴,冗余严重,就不要再说什么单元测试之类的.
为什么MVVM…??
我们最终的目标是以这样一种分布式的方式构建项目,将Android相关的东西放在一个地方,并分离出不需要Android运行的所有其他实体,然后进一步分割非Android相关的片段,从而实现代码模块化、可扩展性、易维护性、测试友好性等。
我们会在公众号博客和技术网站上看到无数关于架构模式的文章和架构设计教程的文章,毫无疑问现在最流行和广泛采用的是MVP~Model—View—Presenter.说明MVP是一个成熟的模式,在一定程度上解决了很多方面的问题,但是也会有上面我提出的问题。当然了没有什么是完美的,总有一个改进的余地。但与此同时谷歌引入了Android架构组件,其中包括ViewModel而不是Presenter,因此证明了谷歌支持MVVM。
可能这些并不能说明MVVM比MVP好,那就让我们看看上述MVP中所面临的几个问题,MVVM是如何来克服的。
1.代码耦合
对于每个Activity/Fragment,我们需要一个Presenter,这是一个硬束缚的规则。Presenter持有对Activity的引用和Activity持有Presenter的参考,两者1:1的关系,就是最大的问题所在。随着视图的复杂性的增加,对这种关系的维护和处理也随之增加。而我们的最终目标以分布式的方式构建项目,对项目做分割,为了实现这个目标并避免这种紧密关系的ViewModel被引入。
ViewModel是负责为activity或Fragment准备和管理数据的类,它还处理activity或Fragment与应用程序的其余部分的通信(例如调用业务逻辑类)。只有View(比如activity)持有对ViewModel的引用,而ViewModel却不持有任何View,这就解决了我们的紧密耦合问题。同时一个View可以引用多个ViewModel。即使对于复杂的视图,我们实际上可以在相同的层次结构中拥有不同的ViewModel。
2.接口冗余
使用这种方式不用写很多的接口,因为ViewModel中会提供数据,如果需要使用数据时可以直接从viewmodel中获取到,不像MVP那样通过接口来回调数据,这样就不会写很多的接口,也不会又接口声明没有使用的情况.
3.可测试性
由于Presenter很难绑定到View,所以编写单元测试变得有点困难,因为View有很多的依赖关系。
ViewModel在单元测试会容易一些,因为它们只是暴露状态,因此可以独立测试,而不需要测试数据将如何被消耗,总之,是不依赖于View的。
这是几个选择MVVM的原因,可能你也有更多原因,期待你的分享!!
一点感想
架构模式是不断发展的,MVVM有能力或者说有潜力变成更加强大,有用,令人惊讶的模式。而MVP已经发展到一个相当高的水平,但金无足赤,没有任何东西是完美的。当然学习MVVM有一点轻微的学习曲线,当时也是试验了好久,但最终它帮助我们克服了一些缺点。有人可能喜欢MVVM,也可能不喜欢MVVM,这完全取决于他们的判断。但我是喜欢的那个,同事也是用了都说好的那种,哈哈,只要我们能达成最终目标,其他事情都无关紧要。
PS:再次重申,这是我个人的一点经验、想法以及我们为什么用MVVM重构项目。请不要怀疑我的意图,我并不是想比较和找出差异。我所想的是分享我的经验和MVP的一些缺点,以及如何用MVVM克服。如果惹闹了您,请轻喷,谢谢