翻译自:

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

更多相关文章

  1. Android之内存溢出(Out Of Memory)的总结
  2. Android(安卓)Studio 使用 System.loadLibrary()的一些问题
  3. 避免Activity内存泄露
  4. Android(安卓)常见的几种内存泄漏 - Handler
  5. 使用Android(安卓)design support library在Eclipse和Android(安
  6. Android工程中javax annotation Nullable找不到的替代方案
  7. Android内存泄漏剖析之AsyncTask
  8. Android(安卓)Handler 避免内存泄漏的用法总结
  9. Android之Resource介绍和使用

随机推荐

  1. php中字符“\n”与“<br />”的区别
  2. php开发的图片验证码显示失败
  3. PHP队列的实现详细操作步骤(通俗易懂)
  4. 如何开启phpstudy中的gd库
  5. php中如何使用websocket(聊天室实例详解)
  6. php中如何在数组指定位置插入数据单元
  7. ubuntu多版本php切换
  8. html是如何与php进行数据交互的
  9. 在树莓派上搭建LNMP环境
  10. PHP 如何上传文件和下载