去年10月底来到新公司。刚接手Android项目的时候,发现项目真的很乱。简单的MVC,MVP看不懂,Activity极其臃肿,业务边界不清晰,所以决定重新分析一下目前主流的几种开发架构,选择适合当前项目的架构形式。这是《我的Android重构之旅》的开篇篇。在这篇文章中,我将依次介绍MVVM、MVP、MVC、AndroidFlux的主流架构设计。深入分析这些架构的代码差异,只是想把它们的设计思路带给大家,让大家更方便的选择适合项目的架构。MVCMVC简单地将整个应用程序分为三个部分:Model、View和ControllerView(视图):管理以位图形式显示在屏幕上的图形和文本输出。控制器:翻译用户输入并根据用户输入操作模型和视图。模型:管理应用程序的行为和数据,响应数据请求(通常来自视图)和更新状态的指令(通常来自控制器)。MVC架构从上图可以看出,View层需要通过Controller通知View层发起事件通知View,然后View从Model获取数据。这在APP中是很难实现的。我们的事件通常是由Activity或View发起和支配的。如果把事件的发起和控制交给Controller处理,往往会出现一些意想不到的问题,比如内存泄漏等,这就导致了MVP这个MVC的变种的出现。Android本身的设计还是符合MVC架构的,但是纯View的XML视图太弱了,我们只能在Activity里面写很多View逻辑,让Activity充当View和View的两个角色Controller,直接导致Activity代码爆炸。相信大多数Android开发者都遇到过一个上千行代码的Acitivty吧!所以,说这个MVC结构其实最后只是一个Model-View(Activity:View&Controller)结构比较合适。MVPMVP架构模式是MVC的变体。许多框架声称遵循MVC架构模式,但实际上实现的是MVP模式。MVC和MVP的区别其实并不明显。我觉得两者最大的区别就是View层可以发起事件。MVC架构在MVP中,Presenter可以理解为一个松散的控制器,里面包含了视图的UI业务逻辑。从视图发送的所有事件将由Presenter通过代理进行处理。同时Presenter也通过view暴露的接口与之通信。沟通。APP中的应用在MVC中,控制器负责响应不同视图的客户端请求的不同动作。但是,与MVC模式不同的是,MVP中的view将所有的action都交给Presenter处理,而MVC中的所有action都对应一个controller的方法调用,web应用中的每一个action都是对某个URL的操作。控制器根据访问的路由和方法(GET等)对数据进行操作,最终选择正确的视图返回。MVC中controller返回的view不直接绑定model,仅由controller渲染,完全无状态,不包含任何逻辑,但MVP中view必须将相应的事件委托给Presenter执行,否则无法响应该事件。以上摘自什么是MVP和MVC,有什么区别?StackOverflow上的模型-视图-控制器部分。从这里可以看出Presenter层的出现帮助我们减轻了Activity的压力,结构也比较清晰,但是View层会多出一些代码来和Presenter进行通信。这是我们不愿看到的结果。MVVM架构就是在这种情况下被提出来的。MVVMMVVM架构模式由微软于2005年诞生,第一次进入Android人员视野是在2015年谷歌推出DataBinding时,随后谷歌陆续推出ViewModels、LiveData、AndroidLoader、Lifecycles等组件适用于MVVM架构。可见,谷歌已经“决定”MVVM作为未来Android开发的第一架构。从名称Model-View-ViewModel来看,MVVM架构由三部分组成,分别是Model、View和ViewModel。ViewModel(视图模型)实际上是PM模式下的表现模型,在MVVM中称为ViewModel。除了我们非常熟悉的Model、View和ViewModel这三个部分,在MVVM的实现中,还引入了一个隐式的Binder层,在MVVM模式中通过它来完成声明式数据和命令的绑定。Binder层MVVM架构将Presenter更名为ViewModel,与MVP模式基本一致。唯一不同的是,它采用了双向绑定(data-binding),View的变化,会自动反映到ViewModel中,反之亦然,这就导致了如果我们要全面采用MVVM,就必须要精通诸如此类的基础组件DataBinding,这让我们很难在项目中引入MVVM。AndroidFluxAndroidFlux是Facebook的Flux架构的Android实现。Flux是Facebook在2014年提出的一种Web前端架构,主要用于处理复杂UI逻辑的一致性(当时是为了解决网页的消息通知问题)。经过实践,发现这种架构可以很好的应用到Android平台上。与MVC/MVP/MVVM等其他模式相比,其文档性好,设计更具体,更适合快速开发和实施。Flux模式最大的特点是数据单向流动,其UI状态更新方式继承了MVC模式的设计思想。Flux不是一个特定的框架,而是一套处理UI问题的模式。AndroidFlux也不是一个特定的框架。您无需导入或集成任何新代码即可使用它。你需要做的就是理解这套思路,遵循这个开发模式。AndroidFluxArchitecture以上内容摘自AndroidFluxQUICKSTART。AndroidFlux的结构设计很容易让我们联想到functional-reactive-programming,而AndroidFlux一直在强调它本身不是一个特定的框架而是一个UI或者数据流的方向,这与众所周知的RxJava设计非常相似idea,所有的事件和UI都可以当成一个数据流来处理。AndroidFlux的数据流只有一个Dispatcher。在AndroidFlux应用程序中,Dispatcher是中心枢纽并管理所有数据流。它实际上管理着Store注册的一系列回调接口,本身没有其他逻辑——它只是一个简单的向每个Store发送Actions的机制。每个Store都会在这里注册自己,并提供自己的回调方法。当ActionCreato传递一个Action给Dispatcher时,应用中的所有Stores都会通过回调接口得到通知。随着App的增长,Dispatcher会变得越来越重要。它可以通过调整回调方法的触发顺序来管理Stores之间的依赖关系。商店可以声明在更新自己之前等待其他商店更新。StoresStore包含应用程序的状态(State)和逻辑(Logic)。它与MVC模式中的Model起着类似的作用,但它管理多个对象的状态——它不像ORM-Model那样是一个单独的数据集。Store负责管理App中一个区域(Domain)的状态,而不是一个简单的ORM数据集。由于AndroidFlux是一系列的语法和结构规范,没有任何组件可以辅助我们开发,所以AndroidFlux的使用难度比较大。暂时不考虑在中小型团队中应用,仅作为知识扩展。综上所述,我们在架构模型的选择上往往没有太多发言权,主要是因为平台本身往往对应用层有自己的设计。我们在开发客户端或者前端应用的时候,只需要遵循平台固有的设计就可以完成应用的开发,但是,有时候,因为项目变得庞大,业务逻辑变得极其复杂,我们也可以考虑实现一个新的在原有架构之上的架构,以满足工程需求。最后由于项目人手不足,我们的项目很遗憾只能选择MVP进行重构,但是其他架构也为我们提供了很好的思路,比如MVVM架构中Google官方提供的绑定组件,AndroidFlux使用UI作为响应式编程的一部分,这些好的地方都值得我们反复揣摩和深入研究。后续文章会和大家一起探讨我们在项目重构中遇到的一些问题,以及我们是如何设计出一个比较简单易用的通用开发框架的。
