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

Design patterns 使用RX通过中介在两个组件之间进行通信,design-patterns,system.reactive,rx-java,Design Patterns,System.reactive,Rx Java,C1和C2是互不了解的组件。C1做C2关心的事情。我使用“经理/调解人”来允许他们之间的沟通 C1和C2都引用这个中介体。C1调用方法mMediator.notifyItemProducerd()和Mediator将“OnItemProducerd”事件转发给它拥有的任何侦听器。C2实现这个监听器接口,并利用它做它想做的事情 class Mediator { List<Listener> mListeners; public void notifyItemProduce

C1和C2是互不了解的组件。C1做C2关心的事情。我使用“经理/调解人”来允许他们之间的沟通

C1和C2都引用这个中介体。C1调用方法
mMediator.notifyItemProducerd()
Mediator
将“OnItemProducerd”事件转发给它拥有的任何侦听器。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!
    }
}
我不喜欢
中介向每个人公开发布事件的能力。虽然我知道这种能力存在于基于侦听器的实现中,但我想知道是否有一种模式允许:

  • C1和C2彼此不了解
  • 只有C1可以发布事件
  • 任何人都可以订阅这些活动

或者我的解决方案是否合理/最佳?

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

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

如果您确实需要只允许
C1
发布消息:在事件中发出
C1
信号,
Mediator
可以将
C1
对象注册为发布者,并基于
C1
事件发出
可观察值,例如
可观察。FromEventPattern
。现在,您的界面可以如下所示

interface Mediator {
    void AddPublisher(C1 pub);
    void RemovePublisher(C1 pub);
    Observable<bool> GetItemsStream();
}
接口中介程序{
void AddPublisher(C1 pub);
无效删除发布者(C1 pub);
可观察的GetItemsStream();
}

(请原谅我的C:)

除了传递价值观,调解人还有什么责任?它管理谁能生产谁能消费吗?还是一个愚蠢的调解人?在我的上下文中,中介是一个发出数据请求和存储状态的对象。组件是视图。它目前不管理谁可以生产或消费,因为它允许任何人通知某个项目已经生产,并允许任何人将自己添加为侦听器。然后,我建议中介拥有一个
IDisposable Publish(IObservable source)
方法和一个
IDisposable Subscribe(IObserver destination)
方法。这样,中介器可以跟踪传入值和传出值,并可以管理错误。否则你最好不要有一个持久的调解人,直接把观察者和观察者联系起来。
interface Mediator {
    void AddPublisher(C1 pub);
    void RemovePublisher(C1 pub);
    Observable<bool> GetItemsStream();
}