翻译自:
https://android.jlelse.eu/why-to-choose-mvvm-over-mvp-android-architecture-33c0f2de5516
什么是体系结构?
通过维基百科,软件体系结构代表软件系统高级别的结构,这一结构的创建.....我们都知道体系结构!
长话短说,体系结构定义并实现了一种特殊的编码框架,定义了一系列设计模式来解决我们开发过程中经常遇到的问题。
问题描述
有一些通用的问题,比如,对于紧耦合的代码,当在某一处小小的改动都会导致其它部分代码的牵连改动,甚至带来各种不确定的bug;较少的重用最终会导致大量的复制-粘贴代码;并不友好的测试等等。
解决办法
Android自身由MVC结构写成。在这个结构中,Activity基本负责了所有的事情。对于简单的应用,这也许足够了,但是随着复杂性的提升,问题的数量也在提高。
目前,有很多有效的体系结构,比如MVP、FLUX、MVI、MVVM等,已经被证实可以有效的解决上面的问题。我们可以选择任意一种方案,只要代码是高可维护性的,我们可以快速自适应改变,所有的开发任务都是顺利的,这就是一个快乐的开发生涯。
最终目标
正如这张图片所展示的,我们的最终目标是:用一个分布式的方法来构建应用,首先,让Android相关的东西在一个地方,其余的不依赖Android运行的东西在一个地方;然后,进一步分裂非Android部分,从而使得代码模块化、可扩展、易于维护、测试友好等等 。
问题来了,为什么选择MVVM呢?
讨论体系结构的演讲和文章不计其数,我们可以认为,最受欢迎和广泛使用过的当属MVP了。这一点也有非常多的炒作,我也很欣赏。MVP是一个很成熟的模式,它在一定程度上解决了实际问题。但是,这并不完全。
我们同意,没有什么是完美的,总有改善的空间。
MVP是成熟的,令人惊喜的,但是,Google引入到Android架构组件中的,是ViewModel,而并非Presenter,我们可以看到Google也是支持MVVM的。
这说明,MVP一定有什么是不美好的。
一个简单的MVP结构类似于这样:
一个简单的MVVM类似于这样:
让我们提出几个问题,当前的MVP面对的,然而使用MVVM却可以避免的。
紧密的耦合度
对于每一个Activity/ Fragment,我们需要定义一个Presenter。这是一个硬性规则。Presenter会持有Activity/Fragment的引用,同时Activity/Fragment也会持有Presenter的引用,这样的1:1关系就是最大的问题。
随着view的复杂度的增加,同时维护和处理它们的关系会变得愈发复杂。
当我们想要快速调整这一设计时,处理起来异常复杂,我们甚至需要重新调整整个关系。
借用我们最终的目标中的一句话:“使用分布式的方式来构建事务”,为了实现这一目标,引入了ViewModel。
ViewModel仅仅用于与业务逻辑层(model)交互,只公开状态/数据;实际上,ViewModel并不知晓谁来使用数据,怎么使用数据。只有View(Activity)持有ViewModel的引用,而 ViewModel却没有持有View的引用,这解决了紧密耦合的问题。一个View可以持有多个ViewModel的引用。
事实上,无论多么复杂的View,我们可以使用不同的ViewModel。
易测试性
因为Presenter对View有较强的依赖,所以写单元测试会有些难度。
ViewModel写单元测试会更友好,因为它仅仅暴露状态/ 数据;所以,今后可以单独执行测试而不必关注数据是否被使用,简而言之,与view进行了隔离。
最终的审判
这些体系结构都在持续的发展着,MVVM具备所有的能力,或者说,它有潜力变得更强大、更有用,同时实现起来令人惊奇。MVP已经发展到一定的级别,但是,它并没有什么完美的。
我同意,MVVM有一点学习曲线,但是它最终帮助我们客服了很多短板。
对于未来,我不确定,但至少“一个适合所有的方案——银弹”是不存在的,单一模式不足以满足需求。我们是否喜欢MVVM,完全取决于自己的判断。只要我们能收获最终的目标,那么这也都不再重要。
PS:这些是我个人的经验和想法,以及我为什么引入MVVM到我们的项目。我的目的并非比较和找出差异。我所做的所有尝试只是为了分享我对于MVP的经验和缺点,以及被MVVM克服的缺点。
https://github.com/ankitsharma6466/AndroidKotlinBoilerplate