C# 观察者模式:仍然紧密相连?

发布于 2024-09-25 12:28:38 字数 305 浏览 6 评论 0原文

好吧,所以我在这里陷入了观察者模式,我读过的几乎所有教程都告诉主题类订阅观察者。

但考虑到封装,这怎么会不紧密耦合呢?他们仍然互相依赖,不是吗?

我的意思是说,主体类必须知道观察者对象才能将其添加到要通知的对象列表中。

因此创建了依赖关系,对吗?

我犯了什么错误?

谢谢!

谢谢大家的回复,

现在我有一些新问题。如果我理解正确的话,处理这个问题的最佳方法是使用接口。所以我会这样做;)

但是,为什么总是谈论代表和事件?事件是代表的一种形式。那么他们为什么不只说事件呢?

ok, so I am stuck at the observer pattern here, almost all tutorials I read tell the subject class to subscribe the observer(s).

But with encapsulation in mind, how is this not tighlty coupled? They still depend on each other know, don't they?

What I mean to say is that the subject Class must know the observer object to add him to the list of objects to notify.

Therefore a dependency is created, right?

What's the mistake I make?

Thanks!

Thanks everybody for the replies,

Now I have some new questions. If I understand correctly the best way to deal with this is with Interfaces. So I will do that ;)

But, Why are the always talking about delegates and events? events ARE a form of delegates. So why aren't they just saying events?

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

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

发布评论

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

评论(7

羁拥 2024-10-02 12:28:38

当你说“知道”时,你是对的,发布者必须了解观察者才能向其发布信息。

然而,它不需要“知道”它,因为它是硬编码的:

  • 观察者总是这个特定的类
  • 总是有这些特定的观察者可用

在其基本形式中,事件是发布者/observer 正在运行,因此您可以轻松地仅使用事件来执行此操作:

public class Observer
{
}

public class Publisher
{
    public event EventHandler SomethingHappened;
}

然后您可以让观察者处理该事件:

public class Observer
{
    public Observer(Publisher pub)
    {
        pub.SomethingHappened += Publisher_SomethingHappened;
    }

    private void Publisher_SomethingHappened(object sender, EventArgs e)
    {
    }
}

public class Publisher
{
    public event EventHandler SomethingHappened;
}

每当发布者引发此事件时,观察者都会收到通知。意识到挂钩事件的行为是“告诉”该类有关观察者的信息,但发布者没有任何有关发布者的硬编码信息,除了有人在听之外。

另一种方法是使用接口:

public class Observer : IObserver
{
    public Observer(Publisher pub)
    {
        pub.Observers.Add(this);
    }

    void IObserver.SomethingHappened()
    {
    }
}

public class Publisher
{
    public List<IObserver> Observers { get; private set; }
}

public interface IObserver
{
    void SomethingHappened();
}

同样,发布者将“知道”观察者,因为它有对观察者的引用,但同样它没有关于哪个类或有多少实例的硬编码信息。

只是警告一下:上面的代码非常有缺陷,至少您应该确保观察者在完成后与发布者“脱钩”,否则系统将出现泄漏。如果您不明白我的意思,请发表评论,我将在示例中进行编辑。

When you say "know", you're right that the publisher must know about the observer in order to publish information to it.

However, it doesn't need to "know" about it in the sense that it is hardcoded that:

  • The observer is always going to be this particular class
  • There is always going to be these particular observers available

In its basic form, events are publisher/observer in play, so you can easily do this just with events:

public class Observer
{
}

public class Publisher
{
    public event EventHandler SomethingHappened;
}

You would then make the observer handle that event:

public class Observer
{
    public Observer(Publisher pub)
    {
        pub.SomethingHappened += Publisher_SomethingHappened;
    }

    private void Publisher_SomethingHappened(object sender, EventArgs e)
    {
    }
}

public class Publisher
{
    public event EventHandler SomethingHappened;
}

Whenever this event is raised from the publisher, the observer is informed about it. Realize that the act of hooking into an event is to "tell" that class about the observer, but the publisher doesn't have any hardcoded information about the publisher, except that there is someone out there listening.

A different way would be using interfaces:

public class Observer : IObserver
{
    public Observer(Publisher pub)
    {
        pub.Observers.Add(this);
    }

    void IObserver.SomethingHappened()
    {
    }
}

public class Publisher
{
    public List<IObserver> Observers { get; private set; }
}

public interface IObserver
{
    void SomethingHappened();
}

Again, the publisher will "know" about the observer in the sense that it has a reference to it, but again it has no hardcoded information about which class or how many instances there will be.

Just a word of warning: The code above is very flawed, at a minimum you should ensure that the observer "unhooks" from the publisher when you're done, otherwise you're going to have leaks in the system. If you don't understand what I mean by that, leave a comment and I'll edit in an example.

游魂 2024-10-02 12:28:38

Observable 类可以接受observe 方法中的接口。该接口在定义主题类的库中定义,然后由订阅者实现。这样,班级就只知道他们应该知道的内容。

The class that is Observable can accept interfaces in the observe method. This interface is defined in the library where the subject Class is defined and then implemented by the subscriber. That way, the classes only know what they are supposed to know.

小帐篷 2024-10-02 12:28:38

C# 中的可观察对象是声明一个或多个事件的对象。一个或多个观察类可能会也可能不会在运行时订阅这些事件。可观察的部分不知道也不关心。

被观察的类不必维护要通知的对象列表。它只需要触发一个事件,否则完全不知道谁在听。

因此,被观察类与观察类之间不存在任何依赖关系。只有观察者必须知道它可以观察到的事件。

托马斯

An observable object in C# is an object that declares one or more events. One or more observing classes might or might not subscribe to these events at runtime. The observable part does not know and does not care.

The observed class does not have to maintain a list of objects to be notified. It just has to fire an event and otherwise is totally agnostic about who is listening.

So there's no dependency whatsoever from the observed class to the observing one. Only the observing one has to know about the events that it can observe.

Thomas

撧情箌佬 2024-10-02 12:28:38

我真的不明白你。但如果您担心 C#/.NET 中的观察者模式。那么 Microsoft 的开发人员已经以 事件的形式解决了您的所有问题

I dont really understand you. But if you are worried about Observer pattern in C#/.NET. Then developers at Microsoft already solved all your problems in form of events.

多孤肩上扛 2024-10-02 12:28:38

我想你读的这个有点错误,是的,主体确实订阅了观察者,但它并没有发起订阅,即 MySubjectClass.Observers += MyObserverClass;

通过使用接口来定义之间的契约主题和观察者允许观察者是实现该接口的任何类。

所以你可以看到这并不是紧密耦合的,即主题没有实例化具体的观察者类。

I think you have read this slightly wrong, yes, the subject does subscribe the observer but it doesn't initiate the subscription, i.e. MySubjectClass.Observers += MyObserverClass;

By using an interface to define the contract between the Subject and the Observer you allow the Observer to be any class that implements the interface.

So you can see this is not tightly coupled, i.e. the Subject isn't instantiating concrete Observer classes.

放低过去 2024-10-02 12:28:38

所有观察者对象和被观察对象都知道它们分别与IObservableIObserver对象交互。 这些对象的确切类型与它们无关 - 它们只关心它们实现了 IObserverIObservable 接口。

All the observer object and the observed object know is that they are interacting with an IObservable and an IObserver object respectively. The exact type of these objects is irrelevent to them - they only care that they implement the IObserver and IObservable interfaces.

笑看君怀她人 2024-10-02 12:28:38

你问“我犯了什么错误?” 我认为您出错的地方是:

我的意思是,主题类必须知道观察者对象才能将其添加到要通知的对象列表中。

You ask "Whats the mistake I make ?" . Your following line is where I think you went wrong:

What I mean to say is that the subject Class must know the observer object to add him to the list of objects to notify.

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