4

我试图绕过在解释 update() 调用时涉及的丑陋条件转换,该调用将要通知其观察者多种类型的事件。另外,我不希望将标志传递给 notifyObservers()/update() 方法。

我不希望观察者必须轮询可观察对象以找出发生了什么变化,我希望通过 update() 方法(或类似方法)将这些新数据提供给观察者。

我有一个解决方案的想法。我为每种类型的通知实例化一个可观察对象。例如: observable 是一个表示硬件设备的对象,它将包含表示其状态的 observable:

public final Observable connectionState = new Observable();
public final Observable dataState = new Observable ();

这样,观察者不需要进行任何类型的查询或条件转换,因为一个观察者,即每个通知类型可以使用一个覆盖的 update() 方法。

在经历了很多挫折之后,这是我能想到的最优雅的解决方案,但是我有一种可怕的感觉,我错过了如何正确使用 Observers/Observables 的要点。

我对该解决方案的主要问题是:

  1. 它仍然涉及演员(至少它不是有条件的)
  2. 由于可观察对象需要是可观察的,因此它们必须是公共成员。虽然这确实允许观察者调用 addObservable(),但它也允许他们调用 notifyObservers()。

我在做正确的事吗?

谢谢

4

3 回答 3

4

您正在努力解决观察者模式的 Java 1.0 实现的局限性。看看这个问题的答案是 java.util.Observable 在哪里使用?

它们没有被使用,因为它们的设计有缺陷:它们不是类型安全的。您可以将任何实现 Observer 的对象附加到任何 Observable,这可能会导致细微的错误。

将它们包装在类型安全的接口中与从头实现模式的工作量大致相同,所以我猜在大多数情况下后者是首选。

与其试图将您的需求硬塞到 java.util.Observer 中,不如只实现您自己的模式版本,以更好地满足您的需求。

于 2011-07-07T09:32:00.083 回答
3

您可以尝试将 Observable 与访客模式配对使用:

class MyObserver implements Observer, EventVisitor {
    public void update(Observable o, Object arg) {
        ((EventAcceptor) arg).accept(this);
    }

    public void visit(SomeEvent v) {
        System.out.println("SomeEvent: " + v.s);
    }

    public void visit(AnotherEvent v) {
        System.out.println("AnotherEvent: " + v.info);
    }
}

interface EventVisitor {
    void visit(SomeEvent v);
    void visit(AnotherEvent v);
}

interface EventAcceptor {
    void accept(EventVisitor v);
}

class SomeEvent implements EventAcceptor {
    public final String s;

    public SomeEvent(String s) {
        this.s = s;
    }

    public void accept(EventVisitor v) {
        v.visit(this);
    }
}

class AnotherEvent implements EventAcceptor {
    public final String info;

    public AnotherEvent(String info) {
        this.info = info;
    }

    public void accept(EventVisitor v) {
        v.visit(this);
    }
}

class MyObservable extends Observable {
    void handleSomeEvent() {
        setChanged();
        notifyObservers(new SomeEvent("some event"));
    }

    void handleAnotherEvent() {
        setChanged();
        notifyObservers(new AnotherEvent("some event"));
    }
}

class Sample {
      public static void main(String[] args) {
          MyObservable observable = new MyObservable();
          observable.addObserver(new MyObserver());
          observable.handleSomeEvent();
          observable.handleAnotherEvent();
      }
}
于 2011-07-07T09:41:55.577 回答
0

您的问题有很多可能的解决方案。如果您觉得 Observable 类不适合您的问题,您可以维护自己的侦听器集合。

interface Listener {
    void onEvent1(Type1 arg);
    void onEvent2(Type2 t2, Type3 t3);
    void onEvent3();
}

List<Listener> listeners = new CopyOnWriteArray<Listener>();

public void addListener(Listener l) { listeners.add(l); }

public void onEvent1(Type1 arg) {
     for(Listener l: listeners) l.onEvent1(arg);
}
于 2011-07-07T09:56:38.210 回答