首页 文章

一个可观察的多个可观察事件

提问于
浏览
3

我正在尝试绕过一个丑陋的条件转换,当解释一个observable的update()调用时,它想要通知它的观察者多种类型的事件 . 另外,我不想将标志传递给notifyObservers()/ update()方法 .

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

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

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

这样,观察者不需要像一个观察者那样进行任何类型的查询或条件转换,即每个通知类型可以使用一个重写的update()方法 .

经过多次挫折之后,这是我能想到的最优雅的解决方案,但是我有这种可怕的感觉,我错过了关于如何正确使用Observers / Observables的观点 .

我的主要问题是:

  • 它仍然涉及演员表(至少它不是有条件的)

  • 由于观察者需要被观察,他们必须是公共成员 . 虽然这确实允许观察者调用addObservable(),但它也允许它们调用notifyObservers() .

我做对了吗?

谢谢

3 回答

  • 3

    您正在努力克服Observer模式的Java 1.0实现的局限性 . 看看this answer的问题是java.util.Observable在任何地方使用?

    它们没有被使用,因为它们的设计有缺陷:它们不是类型安全的 . 您可以将任何实现Observer的对象附加到任何Observable,这可能会导致细微的错误 . 将它们包装在类型安全的界面中与从头开始实现模式的工作量大致相同,所以我想在大多数情况下后者是首选 .

    而不是试图将你的要求卖给java.util.Observer,也许你应该只是实现自己的模式版本,以更好地满足你的需求 .

  • 3

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

    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();
          }
    }
    
  • 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);
    }
    

相关问题