API incorporada en el modo de observador "Headfirst Design Pattern"

Inserte la descripción de la imagen aquí
Además de nuestra propia definición de observadores, también podemos usar la implementación de API en la clase de herramienta java, pero en comparación con la interfaz que implementamos nosotros mismos, tendrá algunos problemas

El lado oscuro de java.util.Observable

Como ha descubierto, lo observable es una "clase" en lugar de una "interfaz" y, lo que es peor, ni siquiera implementa una interfaz.

  1. Primero, debido a que Observable es una "clase", debe diseñar una clase para heredarla. Si una clase quiere tener el comportamiento de una clase Observable y otra superclase al mismo tiempo, se encontrará en un dilema, después de todo, Java no admite herencia múltiple. Esto limita el potencial de reutilización de Observable.
  2. Debido a que no hay una interfaz Observable, no puede crear su propia implementación para usar con la API de Observer incorporada en Java, y no puede reemplazar la implementación de java.util con otra implementación.
  3. Encontrará que el método setChanged () está protegido (definido como protegido), lo que significa: a menos que herede de Observable, no puede crear una instancia de Observable y combinarla en su propio objeto. Este diseño viola el segundo principio de diseño: "Use más composición, menos herencia".
 package Observable;

public interface DisplayElement {
    
    
    public void display();
}
package Observable;

import java.util.Observable;

/**
 * 我们不再需要追踪观察者了,也不需要管理注册与删除(让超类代劳即可)。所以我们把注册、添加、通知的相关代码删除。
 */
public class WeatherDate extends Observable {
    
    
    private float temperature;
    private float humidity;
    private float pressure;

    //我们的构造器不再需要为了记住观察者们而建立数据结构了。
    public WeatherDate() {
    
    }

    //在调用notifuObservers()之前,要先调用setChanged()来指示状态已经改变
    public void measurementsChanged(){
    
    
        setChanged();
        //注意:我们没有调用notifyObservers()传送数据对象,这表示我们采用的做法是“拉”。
        notifyObservers();
    }

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

    //这些并不是新方法,只是因为我们要使用“拉”的做法,所以才提醒你有这些方法。察者会利用这些方法取得WeatherData对象的状态。
    public float getTemperature() {
    
    
        return temperature;
    }

    public float getHumidity() {
    
    
        return humidity;
    }

    public float getPressure() {
    
    
        return pressure;
    }
}
package Observable;


import java.util.Observable;
import java.util.Observer;

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

    //现在构造器需要一Observable当参数,并将CurrentCondi- tionsDisplay对象登记成为观察者。
    public CurrentConditionsDisplay(Observable observable) {
    
    
        this.observable = observable;
        observable.addObserver(this);
    }

    //改变update()方法,增加Observable和数据对象作为参数。
    public void update(Observable obs, Object arg) {
    
    
        if (obs instanceof WeatherDate){
    
    
            WeatherDate weatherDate = (WeatherDate)obs;
            this.temperature = weatherDate.getTemperature();
            this.humidity = weatherDate.getHumidity();
            display();
        }
    }
    @Override
    public void display() {
    
    
        System.out.println("Current conditions: " + temperature
                + "F degrees and " + humidity + "% humidity");
    }
}
package Observable;



import java.util.Observable;
import java.util.Observer;

public class ForecastDisplay implements Observer, DisplayElement {
    
    
    private float curPre =  29.92f;
    private float lastPre = 0;
    private Observable observable;

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

    @Override
    public void update(Observable obs, Object arg) {
    
    
        if (obs instanceof WeatherDate){
    
    
            WeatherDate weatherDate = (WeatherDate)obs;
            lastPre = curPre;
            curPre = weatherDate.getHumidity();
            display();
        }

    }
    @Override
    public void display() {
    
    
        System.out.print("Forecast: ");
        if (curPre > lastPre) {
    
    
            System.out.println("Improving weather on the way!");
        } else if (curPre == lastPre) {
    
    
            System.out.println("More of the same");
        } else if (curPre < lastPre) {
    
    
            System.out.println("Watch out for cooler, rainy weather");
        }
    }
}
package Observable;


import java.util.Observable;
import java.util.Observer;

public class HeatIndexDisplay implements Observer, DisplayElement {
    
    
    private float heatIndex = 0;
    private Observable observable;

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

    @Override
    public void update(Observable obs, Object arg) {
    
    
        if (obs instanceof WeatherDate){
    
    
            WeatherDate weatherDate = (WeatherDate)obs;
            heatIndex = computeHeatIndex(weatherDate.getTemperature(), weatherDate.getHumidity());
            display();
        }

    }
    private float computeHeatIndex(float t, float rh) {
    
    
        float index = (float)((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh)
                + (0.00941695 * (t * t)) + (0.00728898 * (rh * rh))
                + (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +
                (0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 *
                (rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) +
                (0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +
                0.000000000843296 * (t * t * rh * rh * rh)) -
                (0.0000000000481975 * (t * t * t * rh * rh * rh)));
        return index;
    }
    @Override
    public void display() {
    
    
        System.out.println("Heat index is " + heatIndex);
    }
}
package Observable;


import java.util.Observable;
import java.util.Observer;

public class StatisticsDisplay implements Observer, DisplayElement{
    
    
    private float max = 0.0f;
    private float min = 200;
    private float sum = 0.0f;
    private int num = 0;
    private Observable observable;

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

    @Override
    public void update(Observable obs, Object arg) {
    
    
        if (obs instanceof WeatherDate){
    
    
            WeatherDate weatherDate = (WeatherDate)obs;
            sum += weatherDate.getTemperature();
            num++;
            if (weatherDate.getTemperature() < min){
    
    
                min = weatherDate.getTemperature();
            }
            if (weatherDate.getTemperature() > max){
    
    
                max = weatherDate.getTemperature();
            }
            display();
        }
    }
    @Override
    public void display() {
    
    
        System.out.println("Avg/Max/Min temperature = " + (sum / num)
                + "/" + max + "/" + min);
    }
}

prueba

package Observable;

public class WeatherStation {
    
    
    public static void main(String[] args) {
    
    
        WeatherDate weatherDate = new WeatherDate();

        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherDate);
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherDate);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherDate);
        HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherDate);

        weatherDate.setMeasurements(80, 65, 30.4f);
        weatherDate.setMeasurements(82, 70, 29.2f);
        weatherDate.setMeasurements(10, 10, 29.2f);
    }
}

Inserte la descripción de la imagen aquí

para resumir

  • El patrón de observador define una relación de uno a muchos entre objetos.
  • El sujeto (es decir, lo observable) usa una interfaz común para actualizar al observador
  • El observador y lo observable se combinan con acoplamiento suelto (acoplamiento suelto), lo observable no conoce los detalles del observador, solo que el observador implementa la interfaz del observador
  • Al usar este modo, puede enviar o extraer datos del observador (sin embargo, la forma de presionar se considera más "correcta").
  • Cuando hay varios observadores, no puede confiar en una secuencia de notificación específica.
  • Java tiene una variedad de implementaciones del patrón de observador, incluido el genérico java.util.
  • Preste atención a algunos problemas provocados por la implementación de java.util.Observable.
  • Si es necesario, puede implementar su propio Observable, no es difícil, no tenga miedo.
  • Swing hace un uso extensivo del modo de observador, al igual que muchos marcos de GUI.
  • Este modo también se usa en muchos lugares, como: JavaBeans, RMI.

Supongo que te gusta

Origin blog.csdn.net/qq_36694674/article/details/107569505
Recomendado
Clasificación