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

发布于 2024-11-17 17:47:06 字数 770 浏览 2 评论 0原文

参考资料(GOF 设计模式、Head First 设计模式、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 接口中的一个字段?

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

在此处输入图像描述

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

The references (GOF Design Patterns, Head First Design Patterns, http://www.dofactory.com/Patterns/PatternObserver.aspx) that I've read regarding the observer design pattern stipulate that the concrete subject holds a reference to the concrete observer. Much like this:

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

Now, if the concrete Subject is itself implements a Subject interface (or derives from some abstract Subject class) why not make the type in the ConcreteObserver be of that abstract/interface? I.e.

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

Moreover, why not just make it a field in the (e.g.) IObserver interface?

Ultimately, given that the pattern itself seems to loosen the coupling of the Subject to its Observers, why does this appear not to be promoted when coupling an Observer to its subject?

enter image description here

Or is it? I am only basing this on examples that I have read.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

怪我入戏太深 2024-11-24 17:47:06

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

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

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

From your picture, your "update()" method does not receive any information about the state of the Subject, so, if the Observer needs information about this state (as usual in the observer pattern), then it must retrieve it from the ConcreteSubject invoking to the "GetState()" method (not present in ISubject).

An alternative to this schema, would be to pass the state (or a reference to the whole ConcreteSubject) as parameter of "update()" method.

Other general explanations to having a reference to ConcreteSubject instead of ISubject can be that you may want to interact with the ConcreteSubject to invoke business logic (of course not exposed in the ISubject interface).

贱贱哒 2024-11-24 17:47:06

仅仅因为您阅读的定义指出 subject 持有对具体观察者的引用,并不意味着您必须逐字阅读它。

只要主体具有对观察者的引用/链接,无论是具体的还是通过接口/类,该陈述仍然是正确的。

IObserver 和 IObservable 双方都有一个接口是很常见的。我认为你会发现的问题是,当你使主题抽象时,你真的必须努力尝试并找到如何使你的状态变得通用。

Just because the definition you read states subject holds a reference to the concrete observer doesn't mean you have to read it literally.

As long as the subject has a reference/link to the observer whether concrete or via an interface/class the statement remains true.

Its very common to see an interface on both side IObserver and IObservable. I think the issue you are going to find is that when you make subject abstract you are going to really have to try hard and find how to make your state generic.

青柠芒果 2024-11-24 17:47:06

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

Concrete Observer, and Concrete Subject implementation have state too. When state of subject is changes, state of concrete observer is updating too. But sometimes, you might need to see the state of subject, which you do not have, for this, you had better have reference to subject. In the other words, in order to see the state of concrete subject.

泪冰清 2024-11-24 17:47:06

我将尝试提出我的观点。

为什么是混凝土?它们不会造成Subject和Observer之间的耦合吗?

  • 观察者模式主要关注的是1对N模型,而不是N对N,这是通过Observer接口实现的。

    观察者模式主要关注的是1对N模型,而不是N对N模型。 p>

  • 是的,它会导致耦合,并且是有意的,因此每个具体观察者都会准确地得到他想要的东西,而无需多余的“上下文传递”。

耦合性不好,但原理>解耦。

如果通过Subject接口访问具体的Subject,我们就可以在运行时订阅不同的Subject!对吗?

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

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

观察者需要的东西与主体无关,为什么不自己拿呢?

将 ConcreteObserver 耦合到 ConcreteSubject,这样Subject 的工作只是发送通知,而不是数据。

主题:大家好,我的商店开业了!
观察者A:好的,我想我需要那部 iPhone。
ObserverB:好的,我想我需要那台 Windows 计算机。
观察者C:我喜欢iPhone和Windows电脑,也许我应该向A、B询问消息。

I will try to provide my point of view.

Why concrete? Won't they cause coupling between Subject and Observer?

  • The main concern of Observer Pattern is 1-to-N model, not N-to-N, and this is achieved by the Observer interface.

  • Yes, it causes coupling and it's intended, so each concrete observer will get exactly what he wants, without redundant "context passing".

Coupling is bad, but Principle > Decoupling.

If a concrete subject is accessed through the Subject interface, we can subscribe to different Subject at runtime! Right?

  • No, for each concrete observer's update(), it should only do one thing. Single Responsibility Principle.
  • What if one wants to listen to many events? This can be done by Composition, not that lumping all the stuff in a single update().

Some books/online resources authors make update() into something like update(subject, context, varName, ...) then they're assuming what an Observer would need, but

What an Observer will need is not a concern of the Subject, why not take it yourself?

Coupling ConcreteObserver to ConcreteSubject so the Subject's job is just sending notification, not the data.

Subject: Hey everyone my store is open!
ObserverA: OK, I think I need that iPhone.
ObserverB: OK, I think I need that Windows Computer.
ObserverC: I like both iPhone and Windows Computer, maybe I should ask A,B for the news.

你的呼吸 2024-11-24 17:47:06

同意@Rainning,具体观察者可能对 Observable 的不同领域感兴趣。
观察者可以在自己的更新方法中得到他想要的东西。
这是我用c++学习《head First设计模式》的一个例子:

https://github.com/jwbecalm/Head-First-Design-Patterns-in-CPP/tree/main/ch02_Observer

还包括植物类

agree with @Rainning, concrete observers may have interest in different fields from Observable.
The observer can get what he wants in its own update method.
here is an example for my studying 《head first design pattern》 with c++:

https://github.com/jwbecalm/Head-First-Design-Patterns-in-CPP/tree/main/ch02_Observer

also include plantuml class

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文