要为Android应用找到一个好的架构不是一件容易的事情。谷歌似乎不太在乎这个事情,因此在设计模式上,除了Activity 生命周期管理之外,再也没有官方的推荐。
但是,为你的应用打造一个架构是非常重要的。不管你是否喜欢,任何应用最终都会有一个架构。因此你最好是成为一个架构的奠基人,而不是等着它出现。
目前的趋势是采用Uncle Bob在2012年对web应用提出的建议: Clean Architecture。
但是我发现Clean Architecture对于绝大多数安卓应用来说都有点过度设计了。
通常移动应用要比web应用的生命短。移动端技术的发展太快,以至于今天发行的app可能在一年后已经完全过时。
移动应用所做的事情很少。绝大多数的用例都只是数据信息流的消费。从API获取数据,显示数据给用户,很少有输入与写入。
所以它的业务逻辑并不复杂。至少不如后端一样的复杂。虽然你要处理很多平台上的问题:内存,存储,暂停,恢复,网络,定位等等,但是这些都不是业务逻辑。所有app都有这些东西。
因此,绝大多数app似乎都无法从类似于复杂的分层或者工作执行优先级队列中获益。
他们也许只是需要一种组织代码的简单方式,能高效的一起工作,更容易的发现bug。
Flux 架构 被Facebook使用来构建他们的客户端web应用。跟Clean Architecture一样,它不是为移动应用设计的,但是它的特性和简单可以让我们很好的在安卓项目中采用。
要理解Flux,有两个关键的特点
这三个部分都是通过Action来通信的:一个简单的基本对象,以类型来区分,包含了和操作相关的数据。
在Android开发中使用Flux设计规范的目的是建立一个在简单性与易扩展易测试之间都比较平衡的架构。
第一步是找到Flux元素和安卓app组件之间的映射。
其中两个元素非常容易找到与实现。
Actions也不复杂。它们的实现和POJO一样简单,有两个主要属性:
比如,一个显示用户详情的典型action如下:
这可能是Flux理论中最难的部分。
如果你之前使用过Clean Architecture,你可能难以接受。因为Stores承担了原本被分成多层的责任。
Stores包含了application的状态与它的业务逻辑。它们类似于rich data models但是可以管理多个对象的状态,而不仅仅是一个对象。
Stores响应Dispatcher发出的Action,执行业务逻辑并发送change事件。
Stores的唯一输出是这单一的事件:change。其它对Store内部状态感兴趣的组件必须监听这个事件,同时使用它获取需要的数据。
系统中不再需要任何其它组建去了解application的任何状态信息。
最后,stores必须对外公开一个获取application状态的接口。这样,view元素可以查询Stores然后相应的更新UI。
比如,在一个Pub Discovery App 中,SearchStore被用来跟踪被搜索的item,搜索结果以及搜索历史。在同一个应用中,一个ReviewedStore同样包含了浏览pub的列表以及必要的逻辑比如根据review排序。
但是有一个重要的概念需要记住:Stores并不是仓库。它们的职责不是从一个外部源(API或者数据库)获取数据,而是跟踪actions提供的数据。
那么,Flux application是如何获得数据的呢?
在第一幅Flux示意图中我有意跳过了一部分:网络调用。接下来的示意图完善第一幅图并添加了更多细节:
异步网络调用是被一个Actions Creator触发的。一个Network 适配器完成相应API的异步调用并且返回结果给Actions Creator。
最终Actions Creator分发带有返回数据的相应类型的Action。
把所有网络工作和异步工作独立于Stores之外有两个主要的优点:
在这个例子中,你将看到一个使用Flux架构的典型的To-Do应用。
我让项目尽量简单,只演示这个架构如何能够产生组织良好的app。
对于实现的一些评价:
同样的还有Actions数据:它们只是以String类型为key,Object为值的HashMap。这会导致Stores中转换成实际数据的时候发生丑陋的类型转换。而且显然这也不是类型安全的,但这也是为了让我们的例子更好理解。
在安卓应用中其实不存在最佳架构的说法。不过存在适合你当前app的最佳架构。这个架构可以让你和团队其他成员协作起来更轻松,按时完成项目,尽可能的保持高质量与较少的bug。
我相信Flux对于以上提到的特点都有很好的支持。