我只是想向同事解释观察者模式,以便在C#应用程序中使用。我说通过查找一些MSDN文档应该很容易实现。但是,我惊讶地发现MSDN示例偏离了我对Observer模式的教导。请注意,我主要使用Java中的模式,但我的印象是.Net实现几乎相同。
我所知道的模式使用Notify,Subscribe和Unsubscribe方法。在MSDN上解释的这个新实现使用OnNext,OnCompleted,OnError和Subscribe。我能够在几年前找到解释Notify版本的文章。
乍一看,这个新版本似乎不必要地复杂化,让我有些困惑。从什么时候开始实施这个实现,为什么以这种方式实现? Wat是优势吗?
答案 0 :(得分:3)
请记住,.NET Observer接口与MS Reactive Extensions密切相关。如果您想了解OnError / OnCompleted提供的附加功能,这可能是研究的最佳位置。该模式的其余部分几乎匹配原样:
所以真正唯一的新功能是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>
,OnNext
,OnError
完全一致。不同之处在于OnCompleted
情况下我拉输出信息,但在IEnumerator<T>
情况下我推送信息。
当我致电IObserver<T>
时,IEnumerator<T>.Dispose
s的序列被取消。同样,当我在T
返回的Dispose
上致电IDisposable
时,IObservable<T>.Subscribe
的序列将被取消。
当我致电T
时,我拉出 IEnumerable<T>.GetEnumerator
。当我在IEnumerator<T>
。
IObservable<T>.Subscribe
我推送时