没有主题的触发/发布模式

时间:2015-12-17 22:45:54

标签: c# system.reactive reactive-programming

这个让我夜不能寐。假设我有一个简单的界面:

public interface INotifier
{
    IObservable<string> Messages { get; }
    void SendMessage(string message);
}

如果不在内部使用Subject<string>或等效的有状态构造,我如何实现此接口?

我并不意味着这是一场教条式的辩论,更多的是思想实验。如果这是一个真正的问题,我不会考虑使用一个主题来做这件事。我只是好奇,如果有人采取行动,我没有考虑他们可以分享,只是可能扩大我们的集体前景。

2 个答案:

答案 0 :(得分:4)

查看ISubject<T>的定义(稍微简化):

interface ISubject<T> : IObserver<T>, IObservable<T>
{
    void OnValue(T value);
    void OnError(Exception error);
    void OnCompleted();
    IDisposable Subscribe(IObserver<T> observer);
}

现在看一下INotifier的概念等效定义:

interface INotifier : IObservable<string>
{
    IDisposable Subscribe(IObserver<string> observer);
    void OnValue(string value);
}

你看到了问题吗?您的INotifier完全描述了主题的概念,减去OnErrorOnCompleted。虽然不是很明显,但你的问题可以简化为:“如何在没有主题的情况下实现主题?”

在某些时候,订阅者观察到的每个通知都必须来自某个地方。如果这个最终来源是“冷”,你不应该在任何地方需要主题。如果该最终来源是“热门”,则意味着这些值是从您的程序外部推送给您的,而不是IObservable<T>,您必须使用主题。这是不可避免的。在这些情况下,目标是将主题直接置于最终来源。

答案 1 :(得分:1)

我同意@Timothy Shields的观点。您正在尝试在不使用主题的情况下实施ISubject。我也明白你已经简化了界面以保持问题集中(这是值得赞赏的)。但是在这种情况下,我认为需要退后一步,查看系统的分层/设计,以了解为什么你有一个看似是事件代理的类。大多数情况下,当我看到一个主题被使用时,它是有效的(1%的时间),或者实际上系统的结构是需要解决的问题。