在我的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)技术将其传递给客户端。

android - 注入(inject)Otto事件总线而不是使用静态单例的优点-LMLPHP

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

  • 您的依赖关系变得明确。当您通过静态调用获取对对象的引用时,依赖项将隐藏在客户端的实现内部,这会使代码易碎且难以理解。
  • 如果出现这种需求,
  • 将更容易切换到事件总线的其他实现。
  • 注入(inject)的依赖项在测试中更容易模拟
  • 依赖注入(inject)技术会带来一定程度的挣扎实际上是一件好事-如果您在挣扎,这通常表明您做错了事。就您而言,我怀疑您正在滥用事件总线。

  • 我说您有可能滥用事件总线,因为我真的看不到为什么需要在View子类中对其进行引用。我猜您是将有关用户交互的通知发布到事件总线,然后将ActivityFragment订阅到事件总线以拦截这些事件。在这种情况下,事件总线是一种错误的工具(即使效果很好)。

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

    相反,请考虑以下情况:重构您的Views,使其不再有任何内容发布到事件总线(例如,业务需求已更改)。由于Views通知只是通过事件总线与包含FragmentActivity的松散耦合,因此很可能会忘记从FragmentActivity中删除事件处理逻辑,从而留下“死代码”。这很快就会变得凌乱。

    更好的做法是使用观察者设计模式,让Views直接通知ActivitiesFragments,并且仅在处理涉及另一个组件时(不能轻易从FragmentActivity到达;例如,另一个FragmentActivity),这些组件才会发布事件到 Activity 巴士。如果您采用这种方法,则仅需要在“顶级组件”中引用事件总线,并且不会涉及任何麻烦。

    P.S.我最近发布了blog post which introduces some best practices for dependency injection in Android

    10-07 19:08
    查看更多