Java 内置的 Observable 推送通知

huangapple go评论65阅读模式
英文:

Java built-in Observable push notifications

问题

UPDATE 为了更好地理解,我已添加完整的代码。

我正在尝试理解如何使用Java内置的Observer来实现推送(push)和拉取(pull)通知。

Observable 类有两个方法 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(观察者),然后从中获取数据。

对我来说,使用这两种方法都类似于推送(push)通知类型,那么有什么区别呢?
如何使用它来实现拉取(pull)通知类型?

英文:

UPDATE Added the full code to make it easier to understand.

I am trying to understand how to implement push vs pull notifications using Java built-in Observer.

the Observable class has 2 methods notifyObservers() and notifyObservers(Object arg)

according to the docs:
Each observer has its update method called with two arguments: this observable object and the arg argument.

here is my Observer class

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

and in my observable class

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;
    }

I've tried both methods, and both objects can be cast down to WeatherData(the Observer) and then get the data from them.

using both methods seem like push notification-type for me, so what is the difference?
and how can I implement pull notification-type using it?

答案1

得分: 1

notifyObservers()的文档中:

> 每个观察者的update方法会被调用,带有两个参数:这个可观察对象和null。换句话说,这个方法等同于:notifyObservers(null)

这意味着你不应该调用notifyObservers(this) — 这是多余的。通常,参数会是关于改变事件的附加数据。这类似于更现代的事件监听器类(Observable和Observer现在已被弃用),它们的事件除了事件源之外还包含数据。例如,如果你将一个ActionListener添加到一个按钮上,在运行时按下按钮会导致ActionListener的actionPerformed方法被调用,事件中会包含诸如动作发生时间等数据。

拉取通知实际上并不真正是一个通知。拉取意味着你不等待被告知某事发生了;你询问是否有任何事件发生。

一个例子是在你的类中保留一个布尔字段,指示是否发生了任何改变:

public class WeatherData {
    private boolean changed;

    // (其他字段)

    public boolean checkForChanges() {
        boolean hasChanged = changed;
        // 现在有人检查过了,重置改变标志
        changed = false;
        return hasChanged;
    }

    private void measurementsChanged() {
        changed = true;
        // 这里没有其他事情要做。调用者必须“拉取”(请求)新状态,通过调用checkForChanges。
    }
}

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

public class CurrentConditionsDisplay implements DisplayElement { 

    private final WeatherData weatherData;

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

    @Override
    public void display() {
        // 这是拉取操作。
        if (weatherData.checkForChanges()) {
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
        }

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

From the documentation of notifyObservers():

>Each observer has its update method called with two arguments: this observable object and null. In other words, this method is equivalent to: notifyObservers(null)

That means that you should never call notifyObservers(this)—it’s redundant. Normally, the argument would be additional data about the change event. This is analogous to more modern event listener classes (Observable and Observer are now deprecated) whose events contain data in addition to the event source. For example, if you add an ActionListener to a button, pressing the button at runtime causes the ActionListener’s actionPerformed method to be called with an event that contains data such as the time when the action occurred.

A pull notification isn’t really a notification at all. Pulling means you don’t wait to be told that something changed; you ask whether anything has happened.

An example of this would be keeping a boolean field in your class that indicates whether any changes have occurred:

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.
    }

As for how to do the pulling, just keep a reference to a WeatherData object in your CurrentConditionsDisplay class, and check whether it has changed:

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");
    }

huangapple
  • 本文由 发表于 2020年7月27日 03:48:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/63104951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定