不带主题的触发器/发布模式



这个让我彻夜难眠。假设我有一个像这样的简单界面:

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

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

我并不是说这是一场教条式的辩论,更像是一场思想实验。如果这是一个真正的问题,我会毫不犹豫地使用一个主题来做这件事。我只是好奇,是否有人有一种我没有考虑过的方法,他们可以分享,也许可以拓宽我们的集体视野。

查看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>,那么你必须使用主题。这是不可避免的。在这些情况下,目标是将主题直接置于最终来源。

我同意@Timothy Shields的观点。您正在尝试在不使用主题的情况下实现ISubject。我也理解您简化了界面以保持问题的重点(对此表示感谢)。然而,在这种情况下,我认为需要退后一步,查看系统的分层/设计,以理解为什么您有一个似乎是事件代理的类。大多数时候,当我看到一个主题被使用时,它要么是有效的(1%的时间),要么实际上是系统的结构方式,这是需要解决的问题。

相关内容

  • 没有找到相关文章

最新更新