.Net观察者模式的变化。什么时候发生这些,为什么?

时间:2014-12-05 15:49:58

标签: c# .net observer-pattern

我只是想向同事解释观察者模式,以便在C#应用程序中使用。我说通过查找一些MSDN文档应该很容易实现。但是,我惊讶地发现MSDN示例偏离了我对Observer模式的教导。请注意,我主要使用Java中的模式,但我的印象是.Net实现几乎相同。

我所知道的模式使用Notify,Subscribe和Unsubscribe方法。在MSDN上解释的这个新实现使用OnNext,OnCompleted,OnError和Subscribe。我能够在几年前找到解释Notify版本的文章。

乍一看,这个新版本似乎不必要地复杂化,让我有些困惑。从什么时候开始实施这个实现,为什么以这种方式实现? Wat是优势吗?

2 个答案:

答案 0 :(得分:3)

请记住,.NET Observer接口与MS Reactive Extensions密切相关。如果您想了解OnError / OnCompleted提供的附加功能,这可能是研究的最佳位置。该模式的其余部分几乎匹配原样:

  1. 订阅仍然只是订阅。
  2. 取消订阅旨在通过处理订阅返回的上下文来实现。
  3. OnNext对应Notify。
  4. 所以真正唯一的新功能是OnError(提供并行错误报告通道让观察者知道observable已进入错误状态)和OnCompleted(让观察者知道观察者不会成为提供更多的消息。)你可以通过消息中的细节来完成这一点,以指示这些状态转换,但如果你将一个可观察的消息通道视为一种可以进行某种程度上正交的状态更改的消息通道,那么将它们编入内容是有意义的。消息本身的意图。

答案 1 :(得分:1)

要查看的四个界面如下。

IEnumerable<T>
    IEnumerator<T> GetEnumerator()

IEnumerator<T>
    bool MoveNext()
    T Current { get; }
    void Dispose()

IObservable<T>
    IDisposable Subscribe(IObserver<T>)

IObserver<T>
    void OnNext(T)
    void OnError(Exception)
    void OnCompleted()

IEnumerable<T>IObservable<T>接口是 duals IEnumerator<T>IObserver<T>也是如此。 交互式接口IEnumerable<T>IEnumerator<T>使用 pull 语义来描述T s的序列。 被动接口IObservable<T>IObserver<T>使用 push 语义来描述T s的序列。

假设我有一个名为IEnumerator<T>的{​​{1}}。如果我在成功的情况下拨打e后跟e.MoveNext(),我在概念上会得到三件事之一:

  • e.Current返回e.MoveNext(),我得到true
  • T会抛出e.MoveNext()
  • Exception返回e.MoveNext(),我已完成

请注意这些方法与false方法IObserver<T>OnNextOnError完全一致。不同之处在于OnCompleted情况下我输出信息,但在IEnumerator<T>情况下我推送信息。

当我致电IObserver<T>时,IEnumerator<T>.Dispose s的序列被取消。同样,当我在T返回的Dispose上致电IDisposable时,IObservable<T>.Subscribe的序列将被取消。

当我致电T时,我拉出 IEnumerable<T>.GetEnumerator。当我在IEnumerator<T>

中致电IObservable<T>.Subscribe推送