2016-01-20 39 views
2

C1和C2是彼此不知道的組件。 C1會處理C2關心的事情。我使用「經理/調解員」來允許他們之間的溝通。使用RX通過中介器在兩個組件之間進行通信

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暴露給大家公佈事件的能力。雖然我知道在基於監聽器的實現存在這個能力,我想知道,如果有,將允許一個模式:

  • C1 & C2不知道對方
  • 只有C1可以發佈事件
  • 任何人都可以訂閱這些事件

或者我有一個合理/最好的解決方案?

+0

什麼其他調解員,爲直通價值觀的責任?它是否管理誰可以生產,誰可以消費?或者它是一個愚蠢的調解者?或者是其他東西? – Enigmativity

+0

在我的上下文中,調解者是一個製作數據請求和存儲狀態的對象。這些組件是視圖。它目前不管理誰可以產生或消費,因爲它允許任何人通知已經產生了一個項目,並允許任何人將自己添加爲聽衆。 – siger

+0

然後我會建議介體有一個'IDisposable發佈(IObservable源)'方法和'IDisposable訂閱(IObserver目標)'方法。這種方式中介正在跟蹤傳入和傳出的值,並可以管理錯誤。否則,你最好不要有一個長期持久的調解員,只是直接將觀察者連接到觀察員。 – Enigmativity

回答

2

爲了改善當前的解決方案,我會Mediator.publishValue(T value)更換Mediator.getItemsSubject()

  • 摘要通信(消息發佈者不必知道它是如何做
  • 獲得一些對什麼是發佈
  • 還沒到Subject交給不法分子手中控制

如果你真的很需要那只有C1應該被允許發佈消息:有你C1信號,基於與例如C1事件事件Mediator可以註冊C1對象作爲出版商併發出ObservableObservable.FromEventPattern。現在,你的界面可能看起來像這樣。

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

(原諒我的C#:)

相關問題