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