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

时间:2010-10-01 07:48:05

标签: c# design-patterns observer-pattern

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

但考虑到封装,这怎么不紧密耦合?他们仍然依赖彼此知道,不是吗?

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

因此创建了一个依赖项,对吗?

我犯的错是什么?

谢谢!

感谢大家的回复,

现在我有了一些新问题。如果我理解正确,最好的方法是使用Interfaces。所以我会这样做;)

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

7 个答案:

答案 0 :(得分:4)

如果您说“知道”,那么您是正确的,发布商必须了解观察者才能向其发布信息。

但是,从硬编码的角度来看,它不需要“知道”它:

  • 观察者总是会成为这个特殊的班级
  • 总会有这些特殊的观察者可用

在基本形式中,事件是发布者/观察者,因此您可以通过事件轻松完成此操作:

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();
}

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

只是提醒一句:上面的代码存在很大缺陷,至少应该确保观察者在完成时“脱钩”发布者,否则您将在系统中发生泄漏。如果你不明白我的意思,请留下评论,我将在一个例子中进行编辑。

答案 1 :(得分:2)

Observable类可以接受observe方法中的接口。该接口在库中定义,其中定义了主题类,然后由订户实现。这样,班级只知道他们应该知道什么。

答案 2 :(得分:1)

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

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

所以观察到的类与观察类之间没有任何依赖关系。只有观察者才能知道它可以观察到的事件。

托马斯

答案 3 :(得分:0)

我真的不了解你。但是如果你担心C#/ .NET中的Observer模式。然后,微软的开发人员已经以events的形式解决了所有问题。

答案 4 :(得分:0)

我认为你已经读过这个稍微有点错误,是的,主题确实订阅了观察者,但它没有发起订阅,即MySubjectClass.Observers += MyObserverClass;

通过使用接口来定义Subject和Observer之间的契约,您允许Obse​​rver成为实现该接口的任何类。

所以你可以看到它没有紧密耦合,即Subject没有实例化具体的Observer类。

答案 5 :(得分:0)

所有观察者对象和观察到的对象都知道他们正在与 IObservable IObserver 对象分别。 这些对象的确切类型对他们来说是无关紧要的 - 他们只关心他们实现 IObserver IObservable 接口。

答案 6 :(得分:0)

你问“我犯的错误是什么?” 。您认为自己出错的地方就是以下行:

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