面向 EventBus 开发

什么叫面向 EventBus 开发?

即项目为了某些难解的引用找不到的问题,引入了 EventBus,然后后来的开发出于项目工期紧张,或者开发的主观偷懒等原因,滥用 EventBus,大量使用 subscrib – eventbus – observer 的形式来解依赖问题。

危害是什么?

  1. 逻辑零乱,到处跳转,可读性极差。
  2. 代码层级和实际业务层级分离。代码结构连形式上的合理性都没有。
  3. observer 的生命周期极其复杂。时常因为 observer 未被销毁而导致不该有的逻辑。如在 ListView 中,向下滚动,没有销毁 Observer,最终导致通知到已经被滚出屏幕的 Item 中的 Observer。这一点可以通过底层设计来确保销毁,但仍然是一种一旦发生就很隐蔽,难以排查的问题。
  4. 无条件滥用的事件中心,最终等同于 goto。Dijkstra 的那篇经典的《goto statement considered harmful》可以一字不动地抄过来喷事件中心。

考量另外一个点,其实 React Redux 状态容器设计中,Dispatcher 和 Reducer 实质上也是组成了一种事件中心。

  1. 他会不会膨胀?会,怎么办,拆分,Reducer 可以被细粒度地拆解。可读性怎么解决?统一管理的Reducer 可读性比无序要好。
  2. 代码层级和实际业务会不会层级分离?不会,因为只有两层,一层 UI 层,在视图层面上天然地结构合理。子 View,父 View,父父 View。Redux 层,根据事件来分离。
  3. 生命周期管理,会不会有问题?一部分会,因为 Redux 以外的代码足够薄,只有 UI 层。UI 是根据屏幕来渲染的。何况,还有 pure render 的约束,多次渲染、冗余渲染并不会产生什么问题。
  4. 滥用问题导致退化为 goto。事实上,goto 的真正问题在于,你不知道逻辑将会跳往何方。但是 Redux 的真正价值就在于,Redux dispatch (or goto)以后的事件处理机制,包含了统一的 Reducer,异步过程解决方案 aysnc,promise 等,中间件 middleware …

所以这里的问题很清楚,在传统的程序设计中,就不应当有事件中心的存在。只是因为一些特殊的客户端上难解的 Case,比如产品上突发要求的之前互不从属的组件的联动设计,多个 aar 之间的组件相互通信,等业务问题的时候,才会需要引入事件中心,但这绝对不是滥用事件中心的理由。或者就像 Redux 一样,把 UI 层以外的所有逻辑都交付给一套逻辑自洽的 Reducer,Dispacher,Middleware 等等来管理。

写到最后,我觉得我自己都变成 Redux 无脑吹了。然而事实就是如此,就像传统武术对阵 MMA 一样,一个还在使用着玄学气功穴位的概念,另一个已经应用了现代医学、力学、科学地总结了搏击经验,显然是前者被摁在了地板上。