2013-06-18 51 views
0

我使用觀察者模式在Java EE中的,這個想法是讓一個服務火災事件讓許多觀察家。但是,儘管所有觀察者都在監聽同一個事件,但他們中的每一個都只關注事件中指定的特定事件類型。我當前的代碼是這樣的:觀察特定類型的事件

public class Service { 
    public void fireEvent(EventType type) { 
     MyEvent event = new MyEvent(type); 
     fire(event); 
    } 
} 

public class TypeAObserver { 
    public void observeEvent(@Observes MyEvent event) { 
     if (EventType.TYPE_A.equals(event.getType()) { 
      // do something 
     } 
    } 
} 

public class TypeBObserver { 
    public void observeEvent(@Observes MyEvent event) { 
     if (EventType.TYPE_B.equals(event.getType()) { 
      // do something 
     } 
    } 
} 

正如你可以看到,所有的觀察者必須檢查做進一步的操作之前的類型,這增加了源代碼內重複。而且,由於所有觀察者都會收到相同的事件,而其中只有少數實際處理它,所以恐怕這會帶來不必要的性能開銷。

因此,我正在尋找其他方法,而不是在Java EE旁邊最好使用任何新庫,以使每個觀察者僅監聽特定類型的事件。

回答

1
  • 你可以使用一個單獨的隊列/事件,每個事件類型:

公共無效observeEvent(@Observes MyEventOfType1事件)
公共無效observeEvent(@Observes MyEventOfType2事件)

  • 在通用隊列之上構建過濾隊列:過濾隊列過濾事件類型。然後讓消費者觀察已過濾的隊列。

僞代碼:

public class TypeAFilter { 
    List listeners ll = ArrayList<Listener>(); 

    public void add(Listener l) { 
     l.add(ll); 
    } 

    public void observeEvent(@Observes MyEvent event) { 
     if (EventType.TYPE_A.equals(event.getType()) { 
      for (Listener l : ll) { 
       l.observeEvent(event); 
      } 
     } 
    } 
} 

}

這基本上意味着,所述過濾器過濾既是觀察者和觀察到。過濾器正在觀察您的服務,特定事件的使用者將附加到過濾器。

  • 考慮使用instanceof不同的事件類在一起,但我不知道這是否是真的快於equals

  • 使用限定:

公共無效observeEvent(@觀察@ EventType1 MyEvent事件)
public void observeEvent(@Observes @ EventType2 MyEvent event)

查看Oracle的example,和預選賽如何defined

+0

謝謝,但你能解釋一下第2個選項?我不想使用第三種,因爲它可能會在源代碼中引入更多的重複和複雜性,即所有事件的處理大部分都是相似的,只是差別很小。 –

+0

我已經更新了我的答案。而且我添加了另一個選項(限定符),這似乎是在這種情況下最具代表性的事情(但我從未使用它)。 – Beryllium