2017-01-05 43 views
1

假設我有一個班級播音員來播放某些事件。 如:帶過濾器的觀察者模式,在什麼級別進行過濾?

List<Observers> observers = … 

Public void broadcast(Event e) { 
    for (each observer: observers) { 
     observer.observe(e); 
    } 
} 

然後,我有一個名爲EventReceiver類執行以下操作

public void processEvent(Event e) { 
    saveToDatabase(e); 
    broadcast(e); 
} 

現在:新的需求出現,他說,當事件的類型是「富」,我們應該保存它到數據庫但不廣播它。

我應該過濾哪一層?在broadcast.java或EventReceiver.java中?

如:

Public void broadcast(Event e) { 
If (event != foo) { 
    for (each observer: observers) { 
     observer.observe(e); 
    } 
} 
} 

或者

public void processEvent(Event e) { 
    saveToDatabase(e); 
    If (event != foo) { 
     broadcast(e); 
    } 
} 

回答

2

我說processEvent,你的第二個樣品。過濾的責任應來自首先處理事件的代碼主體,然後再決定進行廣播。沒有意義傳播broadcast不會或不應該播出的活動。

0

如果您有2個觀察者,一個廣播和另一個寫入數據庫,則可以使用Decorator模式進行過濾。

class Broadcaster implements Observer { 
    public void process(Event e) { 
     broadcast(e); 
    } 
} 


class DbWriter implements Observer { 
    public void process(Event e) { 
     writeToDb(e); 
    } 
} 



class FilterOutFoo implements Observer { 
    private Observer decorated; 

    public Filter(Observer decorated) { 
     this.decorated = decorated; 
    } 

    public void process(Event e) { 
     if (!e.isFoo()) 
      decorated.processs(e); 
    } 
} 

observed.addObserver(new Broadcaster()); 
observed.addObserver(new FilterOutFoo(new DbWriter())); 
+0

你能詳細說明一下嗎? – JavaDeveloper

0

過濾器應該在EventReceiver.java清楚地實現,你可以升級Broadcast.java類稍後播出的其他事件。

您可以有許多接收器,每個接收器都根據用例實現自己的過濾器。

而且,如Michael指出的那樣,播出不會播出的節目是沒有意義的。

這將像靜音手機塔而不是手機本身。你永遠不會接到任何電話。但是,如果您將手機靜音,則可以決定何時取消靜音。 (對不起,對比:))

0

不要過濾。子類。如果有一個Foo類型的事件,那麼應該有一個類FooEvent。讓觀察員註冊FooEvent通知,以便觀察者只收到他們關心的通知。

問題的根源在於表示多個事件類型的單個Event類。相反,每個事件類型應該有它自己的類和它自己的觀察者列表。