Quantcast
Channel: 英特尔开发人员专区文章
Viewing all articles
Browse latest Browse all 583

Penn Station:一种基于标注的、随特征数量伸缩的发布订阅服务

$
0
0

Edison Wang
Twitter/Vine资深安卓工程师

构建并启动一个应用,既有趣又简单,但接下去就要维护;您不断地增添特性、事件和业务逻辑。 您的团队里增添了新成员,现在要跟踪发生了什么就不太容易了。您需要一种好方法来有条不紊地整理代码。 测试是起步的好方法。 您不断向有限状态机中增添状态,但最终发现无法再跟踪,于是您增添 Otto、EventBus、Dagger、Rx 和其他框架, 但是,在进行代码重构时,为确保调试过程有条不紊,要在编写太多样本文件代码:界面之间找到一个最佳状态却如此困难。

于是 Penn Station应运而生,这是一种利用 EventBus的安卓服务型式:受 iOS 的 Grand Central 启发,将您的应用中的事件设想为人们,他们试图从这里前往那里(请求器/侦听器),因此他们聚集在 Penn Station,在这里,他们可以前往 NJT/LIRR/NYC Metro/etc(不同的进程)。(Penn Station 是纽约一个地铁站,NJT/LIRR/NYC Metro 是新泽西/长岛/纽约市——译者注)

 Penn StationEventBusOtto
声明事件标注标注    标注
事件侦听器接口(2)标注
事件请求工厂标注
事件结果工厂标注
IPC 经由 Parcelable(如需要)
事件生产器标注
请求实施
异步交付
在张贴线程上的事件交付默认
在主线程上的事件交付默认
在背景线程上的事件交付 
请求进程    服务执行器   背景    背景
方便访问语境安卓服务

使用 Penn Station,您实施长时间运行任务的流程就十分方便,因为除了考虑需完成什么任务、何时完成该任务、应发出什么事件外,您不必担心其他任何事情。

设想您在编写一种登录用户的方法:

首先,创建一个实施 BaseAction 的 LoginAction:

  1. 通过 @RequestFactory 标注该 class
  2. 通过 @RequestFactoryWithVariables 标注该 class a. @ClassField(“username”, String.class) b. @ClassField(“password”, String.class)
  3. 通过 @EventProducer 标注该 class a. @ResultClassWithVariables(“Failed”) b. @ResultClassWithVariables(“Success”)
  4. 在 processRequest 内部实施该逻辑。
  5. 通过返回 Failed 事件实施 onError。

现在就可在任何地方使用此 LoginAction,只需声明需要 LoginAction 的任何 class 为 LoginAction.class 的 @EventListener:

  1. 实施 onEventMainThread(LoginActionEventFailed)
  2. 实施 onEventMainThread(LoginActionEventSuccess)
  3. 每当需要时,通过生成的 PsLoginActionAction 调用该动作。

这很好,因为:

  1. 封包:LoginAction 容纳所有逻辑和声明。
  2. 状态解耦: a. 不必担心生命周期:LoginAction 的生存随 Service,而非 Activity。 b. Listeners 有其自己的生命周期,如果其结束,那就结束了。
  3. 编译器辅助的代码重构: a. 如果您新增一个 result 类型,例如 “Expired”,在实施 “LoginActionEventExpired” 之前,所有 listeners 均不编译。 b. 如果要更改 request(请求),例如,增添一个 “birthday” 字段作为登录的必要参数,只需增添一次,然后每处调用 LoginAction 的地方都将要求输入该变量。

我希望,有了这个库,任何人可以编写改善用户体验的有效率、可伸缩和安全可靠的代码。

如果您有任何意见或建议,请不吝指教! :)


Viewing all articles
Browse latest Browse all 583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>