观察者设计模式 - 具体主题和观察者

时间:2011-06-29 14:54:50

标签: design-patterns observer-pattern

我读过的关于观察者设计模式的参考文献(GOF设计模式,头部设计模式,http://www.dofactory.com/Patterns/PatternObserver.aspx)规定了具体主题是对具体观察者的参考。很像这样:

class ConcreteObserver : IObserver
{
    ConcreteSubject concreteSubjectInstance;
    //other code, etc.
} 

现在,如果具体的Subject本身实现了一个Subject接口(或派生自一些抽象的Subject类),为什么不让ConcreteObserver中的类型成为该抽象/接口?即。

class ConcreteObserver : IObserver
{
    ISubject concreteSubjectInstance;
    //other code, etc.
} 

此外,为什么不在(例如)IObserver界面中将其作为字段?

最终,鉴于模式本身似乎放松了主体与其观察者的耦合,为什么在将观察者与其主体耦合时,这似乎不会得到提升?

enter image description here

或者是吗?我只是基于我读过的例子。

4 个答案:

答案 0 :(得分:6)

从您的图片中,您的“更新()”方法没有收到有关主题状态的任何信息,因此,如果观察者需要有关此状态的信息(通常在观察者模式中) ),然后它必须从ConcreteSubject 中检索它,调用“GetState()”方法(不存在于ISubject中)。

此模式的替代方法是将状态(或对整个ConcreteSubject的引用)作为“update()”方法的参数传递。

引用ConcreteSubject而不是ISubject 的其他一般性解释可能是您可能希望与ConcreteSubject交互以调用业务逻辑(当然不会在ISubject接口中公开)。

答案 1 :(得分:2)

仅仅因为您阅读的定义subject holds a reference to the concrete observer并不意味着您必须从字面上理解它。

只要主题具有对观察者的引用/链接,无论是具体的还是通过接口/类,该语句都是正确的。

在IObserver和IObservable两侧都可以看到一个接口。我认为你要发现的问题是,当你制作主题摘要时,你真的必须努力寻找如何来使你的状态变得通用。

答案 2 :(得分:1)

具体观察者,具体主题实施也有状态。当主题的状态发生变化时,具体观察者的状态也在更新。但有时候,你可能需要看到你没有的主题状态,为此,你最好参考主题。换句话说,为了看到具体主体的状态。

答案 3 :(得分:1)

我会尽力提供自己的观点。

  

为什么具体?它们会不会导致主题和观察者之间的耦合?

  • 观察者模式的主要关注点是1-to-N模型,而不是N-to-N,这是通过Observer界面实现的。

  • 是的,它会导致耦合并达到预期的目的,因此每个具体的观察者都将获得所需的内容,而无需多余的“上下文传递”。

耦合不好,但原理>去耦合。

  

如果通过“主题”界面访问具体主题,我们可以在运行时订阅其他主题!对吧?

  • 否,对于每个具体观察者的update(),它只能做一件事单一责任原则
  • 如果要听很多事件怎么办?这可以通过 Composition 来完成,而不是将所有内容集中在一个update()中。

一些书籍/在线资源作者将update()变成类似update(subject, context, varName, ...)的东西,然后他们假设观察者将需要什么,但是

  

观察者所需要的与主题无关,为什么不自己考虑呢?

将ConcreteObserver耦合到ConcreteSubject,以便主题的工作只是发送通知,而不是数据。

主题:嘿,我的商店所有人都开门了!
旁观者A:好的,我想我需要那部iPhone。
ObserverB:好的,我想我需要那台Windows计算机。
观察员C:我同时喜欢iPhone和Windows计算机,也许我应该问A,B这个消息。