2011-06-29 188 views
4

我有一个MyObserver类,用于监听通告程序中的更改。通告程序使用notifyObservers(Object)扩展Observable并通知它的事件。作为参数传递的对象始终是同一个类的实例。问题是每个观察者需要听不同的事件。例如,一个观察者需要听取状态改变的事件以及其他事件的所有类型的事件。我如何用观察者模式来做到这一点?具有两个观察者列表的观察者模式

谢谢。

+0

当你说实现Observable。你的意思是你实现了你自己的Observable接口还是扩展java.util.Observable? – peshkira

+0

究竟,你面临的问题是什么? – Bohemian

+0

我实现了java.util.Observable。 –

回答

3

如果你可以改变设计了一下:

interface MyObserver { 
    public void stateChangeEvent(); 
    public void otherEvent(); 
} 

class MyObserverAdapter implements MyObserver { 
    public void stateChangeEvent() { 
     // some default implementation or no implementation. 
    } 

    public void otherEvent() { 
     // some default implementation or no implementation. 
    } 
} 

class MyStateChangeObserver extends MyObserverAdapter { 
    public void stateChangeEvent() { 
     // implement behavior specific to this class. 
    } 
} 

class MyOtherObserver extends MyObserverAdapter { 
    public void otherEvent() { 
     // implement behavior specific to this class. 
    } 
} 

用法:

MyObserver stateObserver = new MyStateChangeObserver(); 
MyObserver otherObserver = new MyOtherObserver(); 
notifier.notifyObservers(stateObserver); 
notifier.notifyObservers(otherObserver); 
+0

不错。没有默认实现,所以我认为我可以删除MyObserverAdapter。但是,如果我删除它,怎么能只听一个事件而不是全部?也许我需要适配器类。 –

+0

@David适配器可能仍然有用,因为您只需在其他两个类中实现所需的方法。 –

+0

我不明白你的使用例子。主类(观察者)是否必须实现MyStateChangeObserver? –

5

使用notifyObservers(Object arg)版本并创建某种类型的“事件类型”对象。在你的观察类中简单地过滤传入的事件类。

public void update(Object observable, Object arg) { 
    if ((MyEvent) arg.isEventX()) { /* do stuff */ } 
} 
+0

你能告诉我一个简短的例子吗? –

+0

我的意思是关于事件类的一个小例子,但是谢谢你的例子。 –

0

可以测试做可观察类下面的状态变化:

public void update(Observable o, Object arg) 
{ 
    if(o.hasChanged()) 
    { 
     // do something 
    } 
} 

观察者说l任何事情都不需要这个测试。如果您只想监听状态更改,这可能是最简单的方法。

5

我认为观察者模式的Java内置实现不适合您的情况。

实际上,只有一种可观察类型的事件会出现时,通用观察者模式才可用。在观察者设计模式中,全部观察者得到通知总是

所以,在这种情况下,你需要定义自己的可观察到的接口,例如延长一般观察者模式,这种方式:

public enum EventKind { 
    EVENT_A, EVENT_B, EVENT_C; 
} 

public interface Observable { 
    public void registerObserver(EventKind eventKind); 
    public void unregisterObserver(EventKind eventKind); 
    public void notifyObservers(EventKind eventKind); 
} 

然后,你可以实现这个可观测接口内部列表为每种事件通知。如果您愿意,您仍然可以使用Java内置的Observer界面。

这种方法具有以下优点:

  1. 您可以灵活增加更多类型的事件 而不影响 观察员的代码。
  2. 您可以注册任何观察者到任何 事件。
  3. 更新只是观察员 是在 每个事件有效兴趣
  4. 您可以避免观察者端的“空方法”,“事件类型检查”和其他 技巧