Trigger/Publish 没有主题的模式

Trigger/Publish pattern without Subject

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

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。虽然不是很明显,但您的问题可以简化为问题:"How could I implement a subject without a subject?"

在某些时候,订阅者观察到的每个通知都必须来自某个地方。如果最终来源是 "cold,",那么您在任何地方都不需要主题。如果最终来源是 "hot,",这意味着值是从程序外部推送给您的,但不是作为 IObservable<T>,您必须使用主题。这是不可避免的。在这些情况下,目标是将主题直接置于最终来源。

我同意@Timothy Shields 的观点。您正试图在不使用主题的情况下实现 ISubject。我还了解到您简化了界面以保持问题的重点(对此表示赞赏)。但是在这种情况下,我认为需要退后一步并查看系统的 layering/design 以了解 为什么 你有一个 class 似乎是事件经纪人。大多数时候,当我看到一个主题被使用时,它要么是有效的(1% 的时间),要么实际上是系统构建的方式才是需要解决的问题。