注入Otto事件总线而不是使用静态单例的优点

Dan*_*ler 7 android dependency-injection event-bus otto dagger

在我的Android应用程序中,我使用Otto作为事件总线,使用Dagger进行依赖注入.

在Otto的用户指南和许多博客文章中,建议使用注入来获取总线单例.我已经做了一段时间,但最近我更加怀疑如果注入总线比使用简单的静态单例有任何优势.

使用注入时,我必须注入我希望能够在总线上发布UI事件的每个自​​定义View或ViewHolder.尤其是匕首,在我需要公共汽车的地方注入每个班级似乎有点笨拙.当然,我可以通过构造函数或setter方法传递总线,但是如果您考虑具有许多不同视图类型的适配器,那也可能有点笨拙.

我注意到注入总线没有任何好处.在Otto的情况下,注入了一个具体的实现(Bus的一个实例),并且永远不会改变.由于订阅的工作方式,包装Otto进行解耦对于思考是没有任何意义的.

那么,有没有人看到注入奥托的任何优点,我没有看到?

Vas*_*liy 2

在我看来,您绝对应该将事件总线包装在您自己的类中,并使用依赖项注入技术将其传递给客户端。

在此输入图像描述

与简单地通过调用静态getInstance()方法获取引用相比,这种方法有几个优点:

  • 你的依赖关系变得明确。当您通过静态调用获取对对象的引用时,依赖项隐藏在客户端的实现中,这使得代码脆弱且难以理解。
  • 如果出现这种需要,会更容易切换到事件总线的不同实现。
  • 注入的依赖项在测试中更容易模拟
  • 事实上,依赖注入技术引入了一定程度的困难,这实际上是一件好事 - 如果您遇到困难,这通常表明您做错了什么。就您而言,我怀疑您正在滥用事件总线。

我说您可能正在滥用事件总线,因为我真的不明白为什么您需要在子类中引用它View。我猜想您将有关用户交互的通知发布到事件总线,然后订阅ActivityFragment事件总线以拦截这些事件。在这种情况下,事件总线是一个错误的工具(尽管它工作得很好)。

在这种情况下,事件总线是一个错误的工具,因为FragmentsActivity可以直接访问所包含的View对象。您可以获得对这些的引用Views并注册FragmentsActivities侦听器。不需要在这里解耦任何东西。

相反:考虑这样一种情况,您以Views不再发布任何内容到事件总线的方式重构您的事件总线(例如,业务需求发生了变化)。由于通知仅与包含或通过事件总线Views松散耦合,因此您很可能会忘记从和中删除事件处理逻辑,从而留下“死代码”。这很快就会变得混乱。FragmentActivityFragmentActivity

更好的做法是使用观察者设计模式并直接让ViewsnotifyActivitiesFragments,并且只有当处理涉及另一个组件(无法从Fragmentand轻松访问Activity;例如另一个Fragmentor Activity)时,这些组件才会将事件发布到事件总线。如果您遵循这种方法,您将只需要在“顶级组件”中引用事件总线,并且不会涉及任何麻烦。

PS 我最近发表了一篇博客文章,介绍了 Android 中依赖注入的一些最佳实践