【问题标题】:Java built-in Observable push notificationsJava 内置 Observable 推送通知
【发布时间】:2020-07-26 19:48:33
【问题描述】:

更新添加了完整的代码以便于理解。

我正在尝试了解如何使用 Java 内置的 Observer 实现推送通知和拉取通知。

Observable 类有 2 个方法 notifyObservers() notifyObservers(Object arg)

根据文档: 每个观察者都有自己的 update 方法,并使用两个参数调用:这个可观察对象和 arg 参数。

这是我的观察者类

public class CurrentConditionsDisplay implements Observer, DisplayElement {
    private float temperature;
    private float humidity;
    private Observable observable;

    public CurrentConditionsDisplay(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);
    }

    @Override
    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and "
                + humidity + "% humidity");
    }

    @Override
    public void update(Observable o, Object arg) {
        /*
        if (o instanceof WeatherData) {
            WeatherData weatherData = (WeatherData) o;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
        }*/

        if (arg instanceof WeatherData) {
        WeatherData weatherData = (WeatherData) arg;
        this.temperature = weatherData.getTemperature();
        this.humidity = weatherData.getHumidity();
        }

        display();
    }

在我的可观察类中

public class WeatherData extends Observable {
    private float temperature;
    private float humidity;
    private float pressure;

    private void measurementsChanged() {
        setChanged();
        //notifyObservers();
        notifyObservers(this);
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }

    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public float getPressure() {
        return pressure;
    }

这两种方法我都试过了,两个对象都可以转换成 WeatherData(观察者),然后从中获取数据。

使用这两种方法对我来说似乎是推送通知类型,那么有什么区别? 以及如何使用它实现拉通知类型?

【问题讨论】:

  • 我刚读过。我正在阅读 head first 设计模式,它说使用这个内置模式。我可以选择接收推送或拉取通知,但我不知道该怎么做。
  • 拉动 == 轮询

标签: java design-patterns observable


【解决方案1】:

来自the documentation of notifyObservers()

每个观察者都有它的更新方法,它使用两个参数调用:这个可观察对象和null。也就是说,这个方法等价于:notifyObservers(null)

这意味着你永远不应该打电话给notifyObservers(this)——这是多余的。通常,参数将是有关更改事件的附加数据。这类似于更现代的事件侦听器类 (Observable and Observer are now deprecated),其事件包含除事件源之外的数据。例如,如果您将 ActionListener 添加到按钮,则在运行时按下该按钮会导致 ActionListener 的 actionPerformed 方法被调用,其中包含的事件包含操作发生的时间等数据。

拉取通知根本不是真正的通知。拉动意味着您不会等待被告知发生了变化;你问有没有发生什么事。

这方面的一个例子是在您的类中保留一个布尔字段,指示是否发生了任何更改:

public class WeatherData {
    private boolean changed;

    // (other fields)

    public boolean checkForChanges() {
        boolean hasChanged = changed;
        // Now that someone has checked, reset the change flag
        changed = false;
        return hasChanged;
    }

    private void measurementsChanged() {
        changed = true;
        // Nothing else to do here.  Caller must "pull" (request) the
        // new state, by calling checkForChanges.
    }

至于如何拉取,只需在你的 CurrentConditionsDisplay 类中保留一个 WeatherData 对象的引用,并检查它是否发生了变化:

public class CurrentConditionsDisplay implements DisplayElement { 

    private final WeatherData weatherData;

    public CurrentConditionsDisplay(WeatherData observable) {
        this.weatherData = observable;
    }

    @Override
    public void display() {
        // This is the pull.
        if (weatherData.checkForChanges()) {
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
        }

        System.out.println("Current conditions: " + temperature + "F degrees and "
                + humidity + "% humidity");
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 2018-02-17
    相关资源
    最近更新 更多