java事件系统/观察者模式

kognpnkq  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(399)

我已经研究了许多java中observer模式的实现,但没有一个能像我所希望的那样精确地运行。
在我熟悉的编程语言中,可以创建一个事件对象,它可以被侦听器“连接”到,也可以被可观察对象“激发”。有关示例,请参见下面的伪代码。

class MyObservable {

  public Event myEvent1
  public Event myEvent2

  public fireEvent1() {
    myEvent1:Fire()
  }

  public fireEvent2() {
    myEvent2:Fire()
  }
}
class MainClass {

  private onMyEvent1() {
    print("my event 1 fired")
  }

  private onMyEvent2() {
    print("my event 2 fired")
  }

  public MainClass() {
      myObservable = new MyObservable()

      // Pass in the function that i want to be called
      // when myEvent1 is fired.
      myObservable.myEvent1.Connect(onMyEvent1)

      // Pass in the function that i want to be called
      // when myEvent2 is fired.
      myObservable.myEvent1.Connect(onMyEvent2)
  } 

}

我在java中看到的所有实现都要求我为每个事件创建一个单独的接口。这似乎很费劲。我也有听很多事件的类,这意味着我的监听器最多实现10个接口,这在我看来是不对的。在java中真的没有更好/更快的方法来实现observer模式吗?
从上面的伪代码中获得最少的java等效代码,或者仅仅链接到java中observer模式的良好实现,都将受到极大的赞赏!
edit:我忘了提到可以将数量可变的参数传递到fire()方法中(不是在伪代码实现中)。
例如,在myevent1.fire(5,3)中,数字5和3可以用于firevent1(int num1,int num2)

vfhzx4xs

vfhzx4xs1#

下面是伪代码的直接翻译(注意,代码不是线程安全的),并且可以合理地完成您想要的工作。很明显,这不一定是最好的解决方案,而且各种java框架提供了定义和处理事件的不同方法。

public class Event {
  private final List<Runnable> handlers = new ArrayList<>();

  public void connect(Runnable handler) {
    handlers.add(handler);
  }

  public void fire() {
    for (Runnable handler : new ArrayList<>(handlers)) {
      handler.run();
    }
  }
}
``` `Event` 使用基本 `Runnable` 触发事件时要执行的操作的接口。

class MyObservable {

public Event myEvent1
public Event myEvent2

public fireEvent1() {
myEvent1.fire()
}

public fireEvent2() {
myEvent2.fire()
}
}

class MainClass {

private onMyEvent1() {
print("my event 1 fired")
}

private onMyEvent2() {
print("my event 2 fired")
}

public MainClass() {
myObservable = new MyObservable()

  myObservable.myEvent1.connect(this::onMyEvent1)

  myObservable.myEvent1.connect(this::onMyEvent2)

}
}
``` Main 使用方法引用创建 Runnable 注册方法的实现 Event .

iugsix8n

iugsix8n2#

PropertyChangeSupport 会是一个选择。已经有多个事件系统,还有一些库添加了这样的功能(例如,通过注解,所以您不必自己编写锅炉代码)。 EventListenerList 将是另一个现有系统-检查 AbstractTableModel 作为使用示例。

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class Model {
  private PropertyChangeSupport support = new PropertyChangeSupport(this);
  private String                field1  = "";

  public void setField1(String newValue) {
    String oldValue = this.field1;
    this.field1 = newValue;
    support.firePropertyChange("field1", oldValue, newValue);
  }

  public void addField1Listener(PropertyChangeListener listener) {
    support.addPropertyChangeListener("field1", listener);
  }

  public void removeField1Listener(PropertyChangeListener listener) {
    support.removePropertyChangeListener("field1", listener);
  }

  public static void main(String[] args) {
    Model model = new Model();
    model.addField1Listener(e -> System.out.println("field1 changed to: " + model.field1));
    model.setField1("new");
  }
}

相关问题