在我的Android应用程序中,我将Otto用作事件总线,并使用Dagger进行依赖项注入(inject)。
在Otto的用户指南和许多博客文章中,建议使用注入(inject)来获取总线单例。我已经做了一段时间了,但是最近我越来越怀疑注入(inject)总线是否比使用简单的静态单例有任何优势。
通过注入(inject),我必须注入(inject)希望能够在总线上发布UI事件的每个自定义View或ViewHolder。尤其是使用 Dagger 时,将每个类(class)注入(inject)需要公交的地方似乎有点笨拙。当然,我可以通过构造函数或setter方法传递总线,但是如果您考虑使用具有许多不同 View 类型的适配器,那也可能很笨拙。
而且我看不到注入(inject)总线的任何优势。在Otto的情况下,将注入(inject)一个具体的实现(Bus的一个实例),并且永远不会改变。如果考虑的话,将Otto包装起来去耦就没有任何意义,因为订阅的工作方式。
那么,有没有人看到我没有看到的注入(inject)Otto的任何优势?
最佳答案
我认为,您绝对应该将事件总线包装在自己的类中,并使用依赖项注入(inject)技术将其传递给客户端。
与通过调用静态getInstance()
方法简单地获取引用相比,此方法有几个优点:
我说您有可能滥用事件总线,因为我真的看不到为什么需要在
View
子类中对其进行引用。我猜您是将有关用户交互的通知发布到事件总线,然后将Activity
或Fragment
订阅到事件总线以拦截这些事件。在这种情况下,事件总线是一种错误的工具(即使效果很好)。在这种情况下,事件总线是错误工具的原因是,
Fragments
和Activity
可以直接访问包含的View
对象。您可以获取对这些Views
的引用,并将Fragments
和Activities
注册为监听器。无需在这里解耦任何东西。相反,请考虑以下情况:重构您的
Views
,使其不再有任何内容发布到事件总线(例如,业务需求已更改)。由于Views
通知只是通过事件总线与包含Fragment
或Activity
的松散耦合,因此很可能会忘记从Fragment
和Activity
中删除事件处理逻辑,从而留下“死代码”。这很快就会变得凌乱。更好的做法是使用观察者设计模式,让
Views
直接通知Activities
和Fragments
,并且仅在处理涉及另一个组件时(不能轻易从Fragment
和Activity
到达;例如,另一个Fragment
或Activity
),这些组件才会发布事件到 Activity 巴士。如果您采用这种方法,则仅需要在“顶级组件”中引用事件总线,并且不会涉及任何麻烦。P.S.我最近发布了blog post which introduces some best practices for dependency injection in Android。