使用 RX 通过中介在两个组件之间进行通信

Using RX to communicate between two components through a mediator

C1 和 C2 是互不了解的组件。 C1 做 C2 关心的事情。我使用 "Manager/Mediator" 来允许它们之间的通信。

C1 和 C2 都引用了这个中介。 C1 调用方法 mMediator.notifyItemProduced() 并且 Mediator 将 'onItemProduced' 事件转发给它拥有的任何侦听器。 C2 实现了这个侦听器接口并用它做它想做的事。

class Mediator {
   List<Listener> mListeners;

   public void notifyItemProduced() {
        for each listener in mListeners
            listener.onItemProduced();
   }

   public void addListener(Listener listener) { ... }

   public interface Listener { 
       void onItemProduced();
   }
}

class C1 {
    public void onClick() { mMediator.notifyItemProduced(); }
}

class C2 {
    public C2 { mMediator.addListener(this); }

    public void onItemProduced() { 
        // do something here!
    }
}

我正在评估用 RX 实现替换此模式。我认为 Mediator 应该保留 C1 发布和 C2 订阅的 Subject

class Mediator {
   Subject<Boolean, Boolean> mItems;

   public Subject<Boolean, Boolean> getItemsSubject() {
        return mItems;
   }

   public Observable<Booelan> getItemsStream() {
       return mItems.asObservable();
   }
}

class C1 {
    public void onClick() { mMediator.getItemsSubject().onNext(true); }
}

class C2 {
    public C2 { mMediator.getItems().subscribe(b => doSomething(b)); }
}

我不喜欢 Mediator 向所有人公开发布事件的能力。虽然我知道这种能力存在于基于侦听器的实现中,但我想知道是否有一种模式允许:

或者我有什么reasonable/best解决方案?

为了改进您当前的解决方案,我会将 Mediator.getItemsSubject() 替换为 Mediator.publishValue( T value ) 以便

  • 抽象通信(消息发布者不需要知道它是如何完成的
  • 对发布的内容进行一些控制
  • 不要将 Subject 交给坏人

如果您确实需要只允许 C1 发布消息:在 事件 中发送您的 C1 信号,Mediator 可以将 C1 对象注册为 publishers 并根据 C1 事件发出 Observable 值,例如Observable.FromEventPattern。现在,您的界面可能如下所示。

interface Mediator {
    void AddPublisher(C1 pub);
    void RemovePublisher(C1 pub);
    Observable<bool> GetItemsStream();
}

(原谅我的 C# :)