在web开发中存在很多已经非常成熟的框架,比如ROR(Ruby)、Django(Python)、Play(scala&java)还有名目众多的Java家族。框架会遵循一定的模式,这样使得常见的问题可以很容易的解决,使开发人员更专注于业务逻辑。
但是在移动开发(Android)上,很遗憾的是并没有好的架构的可以使用。通常我们在写App的时候会调研一堆开源项目,每个项目都致力于解决一部分问题(这是对于有经验的开发人员而言的,熟知各种开源项目,对于新手的往往重复造了很多轮子而且还造的不好):
- Retrofit、Volley 等用来解决大量的网络请求问题
- UIL、Picasso、Fresco、Glide 等用来解决图片加载的问题
- ORMLite、SugarORM、GreenDAO等提供ORM框架
- RoboGuice、ButterKnife、Dagger等提供依赖注入的功能
- 各种开源的UI库,提供特殊的UI需求,比如下拉刷新等等
- … …
在开源精神大行其道的今天,这样的项目实在太多,在 Trinea 的Github页面上收集了很多。但是这些项目都是用来解决一部分问题的,如何在自己的代码中有效的组织这些项目成了新的开发难题。而这绝大多数时候依赖于开发人员的工作经验(所以现在拥有4、5年开发经验的程序员是很热门的)。一个有经验的程序员,会依靠他过往的项目经验,有效地组织这个开源项目(也即是我们常说的,我们的App就是用几个开源库拼凑的)。
但是在Web开发中,即使是新手也可以很容易上手项目写出高质量的代码,调度、更换、修改不同的功能组件。思考其中的原因,是源于在Web上他们不是从零写代码,而是基于某个框架写代码,而框架已经约定了数据库、网络、请求路由、分层结构等等,这使得更换某个功能组件就像写一行“HelloWorld”一样简单。所以在移动开发日渐成熟的今天,我们也需要一套架构来帮助我们约定一些规则,解决常见的问题,比如数据存储、网络请求、UI状态和底层数据的同步方式。
而一旦有了架构,我们也可以基于此更深入地讨论问题。
U+2020项目
A sample Android app which showcases advanced usage of Dagger among other open source libraries.
U+2020是安卓届的大神JakeWharton写的一个开源项目,他的目的是提供一个示例,来告诉开发者如何用Dagger和各种不同的开源组件一起协调工作。这是一个很好的开始,大部分Android从业人员都应该去看一看这个项目,通过它我们可以了解到别人是如何构建项目的,而不是生活在自己的小圈子里面。但是这还不够,这个项目仅仅是一堆源码,学习起来也是比较吃力地,缺少文档说明,同时也很难简单的透析作者的思想 —— 他究竟是按照什么样的思路来构建这个App的。所以我们需要的是更抽象的指导加上具体的示例,这样才能提供更平滑的学习曲线。
AndroidFlux
注:Flux是开源大户Facebook在去年F8上提出的一种前端UI交互架构
在此之前写过一篇文章曾经用过的几种Android”架构“例数过去在Android平台经历的“架构”上的磕磕碰碰。那时在Android届已经逐渐流行起一种UI架构方式——MVP(为什么不是MVC,看完UI架构小史3(MVC/MVP/MVVM)你心中会有答案)。我个人也是挺喜欢MVP(更爱Flux_)的,MVP模式可以方便的解决Android上的大部分问题,但是MVP模式本身存在的问题在于——难以驾驭!MVP模式发展了很多年,但是并没有任何组织来维护这种架构,它更像是课本上的一个名词定义,不同的人用MVP会写出不同的代码。这非常不利于团队协作,当代码量越来越大,协作开发人员越来越多的时候,不同成员之间会因为理解的不同导致项目的代码逐渐变得难以维护。
所以当我第一次见到的Flux的时候,有种莫名的感激,通过Flux详细的文档可以准确/深入的了解这种架构设计的初衷,每个模块设计的用意,减少原来MVP/MVC的各种误解。另一方面是实用,经过在真实项目中的应用,Flux是非常适合移动平台的(Android已经验证,iOS没有实践),移动软件的特点是用户体验第一、更新速度快,存储放在云端,本地存储仅作缓存使用,整个App设计的重心是围绕着用户体验来设计的。Flux的优点是适合处理复杂的用户界面,支持快速开发、测试简单,UI可预测。在用Flux开发Android应用的过程中,隐隐感觉到一个字——“爽”!
“为Android选择一个合适的架构?” “当然是Flux!”
注:最近(17/09/13)我觉得应该注释掉这句话。主要是因为在团队中推广的时候我发现,学习flux的成本还是很高的,一方面是这种架构风格比较新颖不符合大家习以为常的MVC概念(本质一样),另一方便大家都喜欢自己已经熟悉的技术,对于新的需要一定的探索,还需要在产品上做实验。所以在推广过程中并不顺利,最后重新了回到了MVC架构。注意度读过之前关于架构小史的同学应该知道,此处的MVC是泛指类似的架构。在我们的项目中,分为明确的UI层和大业务层,UI层使用MVC类架构,大业务层使用分层架构,具体为小业务层和领域层,领域层负责每个领域具体的事项,比如消息存储和消息发送是两个领域层的实例,而在小业务层调度领域层的实例实现具体的业务,比如发消息(小业务层和领域层统称为大业务层)。同时我们小业务层实现了不同子业务的相互通信,比如消息发送成功之后,需要通知其它业务比如消息计数服务。通信机制采用EventBus类似的方案,只是对于EventBus的使用仅限制在业务之间!限制EventBus的时候有很大的好处,因为它就像goto语句一样容易出问题。层与层之间,业务和UI之间通过工厂模式提供接口,这样可以隐藏每个层内部的具体实现。我们在UI层和业务同时实现了缓存逻辑,UI层的缓存只能缓存一个页面的数据,而业务层的缓存可以覆盖多个页面,因为不同UI实际上依赖于同一个小业务接口,它们的数据是一致的。我们没有使用Rx方案也没有使用Kotlin,尽量保持架构的精简,我们自己实现了一套简单的异步调用接口,比如:
Async.UI()/Ansync.Background()
这是一套轻量级的方案,总共代码不超过500行,另外我们的代码从来就不会出现内存泄漏,因为我们的UI层和业务层交互的地方,使用了动态代理还代理了UI对象。这个方案也非常简单,proxyView = ViewWrapper.Get(uiView)
只需要这一句话就解决了内存泄漏问题。
最后我们发起了AndroidFlux项目,在这个项目中我们把Flux架构移植到了Android平台。提供详细的说明文档,尽量去规范化一个完整App的架构设计,方便不同的人写出同样质量的代码。同时也在这里分享在开发过程中遇到的问题和处理问题的方法。
备注
Flux并不是静止的,MVP在过去几年已经不再发展,对于新的平台新的开发环境,能否很好的使用取决于开发人员的个人能力。而Flux一直在演变以适应最新的开发技术/环境,目前为止,Flux已经衍生出适应不同业务场景的其他架构,目前最流行的是Redux。
AndroidFlux项目一览
用Flux构建Android平台的HelloWorld应用
AndroidFlux项目不仅仅做简单的翻译工作,还需要提供Android平台的适配,需要大家的共同参与,分享开发过程中的经验心得,共同维护项目的发展。