2011-10-22 89 views
1

我是觀察者模式的忠實粉絲。在我們的代碼中,我們在很多地方使用它來將服務彼此分開。然而,我看到它在很多地方都執行得不好,因爲有很多需要擔心:將觀察者模式拉入服務

  • 異常處理 - 不希望偵聽器引發運行時異常。
  • 長時間運行的監聽程序阻止主線程
  • 併發修改偵聽程序列表,因爲我們正在遍歷它。

更重要的是,我們最終重複遍佈這個代碼。本着DRY的精神,我希望將所有通知問題提交到單一服務中。一些僞代碼:

Interface NotificationService 
    // register the listener to receive notifications from this producer 
    registerAsListener (NotificationProducer, NotificationListener) 

    // Sends a notification to listeners of this producer 
    sendNotification (NotificationProducer, Notification) 

    // Sends a notification in a background thread 
    sendAsynchNotification (NotificationProducer, Notification) 

    // Listener no longer receives messages from this producer 
    removeListener(NotificationProducer, NotificationListener) 

我的問題是這樣的:我是否因此失去了觀察者模式的原始點?我是否通過在模式的兩側引入另一個依賴來犯錯誤? Listener和Producer現在都會對NotificationService有額外的依賴。

您對此有何看法?

回答

1

你對你的疑慮和疑問是正確的。多次實現觀察者模式似乎是簡單的重複。 你也是對的,上面的解決方案確實失去了模式的目標。

剛剛實施的是(全球?)事件總線。它是生產者和聽衆的矩陣。這對許多應用程序很有用(請參閱GWT的事件bus)。

但是,如果您只是希望儘量減少代碼重複,同時保持模式。您可以刪除偵聽器和服務之間的耦合,使用上述接口的縮小版本作爲觀察類的成員。所以註冊和通知的邏輯只寫一次。 觀察到的類只是將註冊和通知邏輯委派給服務。

class ObservedClass implements Observable { 
    NotificationService notificationService = new NotificationServiceImpl (this); 
    .... 
} 

interface NotificationService { 
    // register the listener to receive notifications from this producer 
    registerAsListener (NotificationListener) 

    // Sends a notification to listeners of this producer 
    sendNotification (Notification) 

    // Sends a notification in a background thread 
    sendAsynchNotification (Notification) 

    // Listener no longer receives messages from this producer 
    removeListener(NotificationListener) 
+0

這是一個很好的折衷!我可能會從構造函數中取出NotificationProducer依賴項,以便通過IoC注入。生產者將隱含地成爲通知服務注入的類。謝謝。 – djcredo

+0

我記得還有一個評論 - 你允許引用你的部分構造的對象以轉義到NotificationService(當傳遞「this」時)。這可能是不明智的。 – djcredo

+0

我同意你的最新評論,如果可能的話,最好避免將其傳遞給服務。 – LiorH