我发现我在代码中经常这样做(使用 Guice 作为我的 DI 框架):
public class SomeObserver implements IObserver {
@Inject
SomeObserver(IObservable observable) {
observable.subscribe(this);
}
// Snip
}
我最近想到,在测试时,我现在需要至少将一个模拟传递到我的程序中,这不一定是最糟糕的事情,但它确实取决于至少将依赖项绑定(bind)到 IObservable
。界面。另一种选择是在生产中这样做:
public class SomeModule extends AbstractModule {
// snip
@Provides
protected SomeObserver provideSomeObserver(IObservable observable) {
SomeObserver newObject = new SomeObserver();
newObject.subscribe(observable);
}
}
然后在测试中,我什至不必引用 Observable
.但是,如果我想更改构造函数,则模块也必须更改(在第一个示例中没有)。
哪个更好?还是有更好的第三种选择?
更新:我想谈谈我的用例。
考虑一个数据处理应用程序,其中数据源是 Observable。我不希望数据源了解系统的其他部分 ( Separation of Concerns )。数据被过滤到至少三个不同的观察者中,他们从事独立的任务。我想保持数据源可交换 - 出于测试、关注点分离等原因,所以数据源只是实现了我定义为 Subscribable<Observer>
的内容。接口(interface),然后你可以调用.subscribe(this)
.
然后,我使用依赖注入(inject)和模块来确定布线的确切方式。该解决方案还允许我 decorate如果我选择可观察对象,使用注释来阐明注入(inject)。
所以,从本质上讲,我正在使用依赖注入(inject)来管理布线,这正是我最初认为的用途;比如说,创建一个 ObservationManager
好像很多boilerplate为了一点好处。但同样,我可能会遗漏一些东西。
最佳答案
看起来您有点滥用依赖注入(inject)。
依赖注入(inject),顾名思义,就是通过解析类的依赖来解决一个问题。但在语义上观察者和可观察者并不相互依赖。它们确实不应被视为依赖项。
设置观察者与可观察对象的关系本身就是一项单独的任务,因此理想情况下,您应该有一个依赖于观察者和可观察对象的第三方实体,并在它们之间建立关系。在这种情况下使用事件总线看起来非常正交,因为它仍然归结为订阅,而订阅应该在某个地方完成。
事实上,您已经注意到在这种情况下使用模拟很奇怪,这表明您正在尝试将根本不是依赖项的东西用作依赖项。对于普通依赖项(由类直接使用),提供模拟对象是完全可以的,毕竟它们正是为此而设计的。
关于java - 依赖注入(inject)和观察者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22388408/