什么叫面向 EventBus 开发?
即项目为了某些难解的引用找不到的问题,引入了 EventBus,然后后来的开发出于项目工期紧张,或者开发的主观偷懒等原因,滥用 EventBus,大量使用 subscrib – eventbus – observer 的形式来解依赖问题。
危害是什么?
- 逻辑零乱,到处跳转,可读性极差。
- 代码层级和实际业务层级分离。代码结构连形式上的合理性都没有。
- observer 的生命周期极其复杂。时常因为 observer 未被销毁而导致不该有的逻辑。如在 ListView 中,向下滚动,没有销毁 Observer,最终导致通知到已经被滚出屏幕的 Item 中的 Observer。这一点可以通过底层设计来确保销毁,但仍然是一种一旦发生就很隐蔽,难以排查的问题。
- 无条件滥用的事件中心,最终等同于 goto。Dijkstra 的那篇经典的《goto statement considered harmful》可以一字不动地抄过来喷事件中心。
考量另外一个点,其实 React Redux 状态容器设计中,Dispatcher 和 Reducer 实质上也是组成了一种事件中心。
- 他会不会膨胀?会,怎么办,拆分,Reducer 可以被细粒度地拆解。可读性怎么解决?统一管理的Reducer 可读性比无序要好。
- 代码层级和实际业务会不会层级分离?不会,因为只有两层,一层 UI 层,在视图层面上天然地结构合理。子 View,父 View,父父 View。Redux 层,根据事件来分离。
- 生命周期管理,会不会有问题?一部分会,因为 Redux 以外的代码足够薄,只有 UI 层。UI 是根据屏幕来渲染的。何况,还有 pure render 的约束,多次渲染、冗余渲染并不会产生什么问题。
- 滥用问题导致退化为 goto。事实上,goto 的真正问题在于,你不知道逻辑将会跳往何方。但是 Redux 的真正价值就在于,Redux dispatch (or goto)以后的事件处理机制,包含了统一的 Reducer,异步过程解决方案 aysnc,promise 等,中间件 middleware …
所以这里的问题很清楚,在传统的程序设计中,就不应当有事件中心的存在。只是因为一些特殊的客户端上难解的 Case,比如产品上突发要求的之前互不从属的组件的联动设计,多个 aar 之间的组件相互通信,等业务问题的时候,才会需要引入事件中心,但这绝对不是滥用事件中心的理由。或者就像 Redux 一样,把 UI 层以外的所有逻辑都交付给一套逻辑自洽的 Reducer,Dispacher,Middleware 等等来管理。
写到最后,我觉得我自己都变成 Redux 无脑吹了。然而事实就是如此,就像传统武术对阵 MMA 一样,一个还在使用着玄学气功穴位的概念,另一个已经应用了现代医学、力学、科学地总结了搏击经验,显然是前者被摁在了地板上。