之前,我简单介绍了Android中的事件驱动编程,并给出了事件驱动的HelloWorld应用代码。
现在我们可能面对另一个问题:我们如何正确地使用事件驱动开发,同时不陷入混乱?这篇文章,我将提供一个基于事件驱动规划应用程序的建议性架构,但也能用于创建更通用类型的应用。
这个架构我已经用了一段时间,并做了一些改动。使用事件和MVP模式确保了向应用添加特性非常简单。同时缩减了重构和重写之间的周期,所以写出的软件有效期更长,质量更高。
第一个术语:MVP
MVP代表模型、视图、表示器(Model View Presenter),是个编程范型,定义了一个软件系统中需要实现的三种基本实体:
模型:要渲染什么
视图:怎么渲染
表示器:处理模型和视图间的通信。表示器用模型中的内容来更新视图,抽象视图之下的复杂度。
MVP(以及其他编程范型)更像一个概念而不是概念坚实的框架,所以基本上没有严格的规则。Android并没有实现一个纯MVP模式,但是包含一些元素:
- 用户界面(视图)定义在XML文件中。
- 我们通过inflate视图,然后更新这些视图来扩展类(Activity,Fragment)。
在所有MVP模型的组件中,表示器在Android中没有直接的表示。但它是个重要的组件:想象下我们需要从web service获取数据而不是数据库。如果我们遵守MVP方法,这一点是微不足道的。
事件驱动支撑的架构
下面的架构目标在于让基于事件驱动的应用实现更简单。同时还有其他优势,比如高模块化、易于测试。
我们将创建自己的Application实例。该实例将容纳一个EventBus Registry,这个类包含事件总线订阅者的完整列表(稍后再细说)。我们的Application将会注册所有的订阅者,然后在终止时注销。
EventBusRegistry
该类基本上是包含事件总线所有订阅者的注册器。我将自己的订阅者命名为PluginController,因为你可以随意插拔而不影响应用的工作(当然,如果不插入它们,就无法监听事件)。我觉得这种命名可能会误导读者,所以本文中我命名为Subscriber。
EventBus Registry保留了EventBus(是个静态类)的一个引用,这样它才可以注册订阅者。
订阅者(Subscriber)
订阅者将是唯一可以监听事件的类。这些类可以包含一个或多个onEnter()方法。订阅者接到一个事件就会执行动作。简单例子:你可以定义一个接到“PerformCallEvent”时执行调用的订阅者。
订阅者也可以在事件到来时,发送事件到EventBus。
表示器(Presenter)
表示器执行动作。视图会分配优先顺序,它们一个接一个地执行。它们也可以发送事件到EventBus。
此架构使用单个Activity。肯定有赞成或反对的声音,但是由于我们使用不同的Fragment表示屏幕,使用单个Activity会让事情更简单(记住,作为一个开发者,你的主要目标是少编码)。
我把示例项目上传到了GitHub,这个项目包含一个登陆页面,会触发事件执行登陆和加载后续的片段。项目架构如下:
EventBus Registry有很多基础类,Activity和Subscriber(你可能想根据项目需求增加一个Fragment类)。Application,EventBus和EventBus Registry可以根据项目进行定制(因此加上了ED前缀,Event-Driven)。
扩展该应用来添加新特性的话,基本上每个特性都需要新事件、订阅者、表示器和视图。遵守这个模式可以保证应用是可伸缩的,代码是解耦的,因此容易测试和理解。