"Headfirst Design Pattern" Observer Mode

Design Principles

Work hard for loosely coupled design between interactive objects

Observer mode

Define one-to-many dependencies between objects, so that when an object changes state, the dependent objects will be notified and automatically updated
Insert picture description here

Insert picture description here
Insert picture description here

We define a theme interface and an observer interface, plus an interface for displaying data. The
theme interface mainly includes registering observers, removing observers, and pushing content to observers after modifications.
Our observers can join at any time. Left
and our observer interface mainly implements data reception and update

package Observer;

public interface Subject {
    
    
    public void registerObserver(Object o);
    public void removeObserver(Object o);
    public void notifyObserve();
}
package Observer;

public interface Observe {
    
    
    public void update(float temp, float humidity, float pressure);
}
package Observer;

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

import java.util.ArrayList;
public class WeatherDate implements Subject{
    
    
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherDate() {
    
    
        observers = new ArrayList();
    }


    @Override
    public void registerObserver(Object o) {
    
    
        observers.add(o);
    }

    @Override
    public void removeObserver(Object o) {
    
    
        int i = observers.indexOf(o);
        if (i > 0)
            observers.remove(i);
    }

    @Override
    public void notifyObserve() {
    
    
        for (int i = 0; i < observers.size(); i++) {
    
    
            Observe observe = (Observe) observers.get(i);
            observe.update(temperature, humidity, pressure);
        }
    }

    public void measurementsChanged(){
    
    
        notifyObserve();
    }

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


And we also defined four display boards
display boards all contain a reference to a theme object, used to register the observers
after when we call setMeasurements's theme () method, and then calls measurementsChanged () and notifyObserve ()
final Will push the updated content to every observer

package Observer;

/**
显示当前的温度和湿度的展示板
**/
public class CurrentConditionsDisplay implements Observe, DisplayElement{
    
    
    private float temperature;
    private float humidity;
    private Subject weatherDate;

    public CurrentConditionsDisplay(Subject weatherDate) {
    
    
        this.weatherDate = weatherDate;
        weatherDate.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
    
    
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }
    @Override
    public void display() {
    
    
        System.out.println("Current conditions: " + temperature
                + "F degrees and " + humidity + "% humidity");
    }
}
package Observer;
/**
显示当前湿度的适宜程度展示板
**/
public class ForecastDisplay implements Observe, DisplayElement {
    
    
    private float curPre =  29.92f;
    private float lastPre = 0;
    private WeatherDate weatherDate;

    public ForecastDisplay(WeatherDate weatherDate) {
    
    
        this.weatherDate = weatherDate;
        weatherDate.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
    
    
        lastPre = curPre;
        curPre = humidity;
        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 Observer;
/**
显示当前酷热度展示板
**/
public class HeatIndexDisplay implements Observe, DisplayElement {
    
    
    private float heatIndex = 0;
    private WeatherDate weatherDate;

    public HeatIndexDisplay(WeatherDate weatherDate) {
    
    
        this.weatherDate = weatherDate;
        weatherDate.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
    
    
        heatIndex = computeHeatIndex(temp, humidity);
        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 Observer;
/**
显示当前温度最大最小和平均值的展示板
**/
public class StatisticsDisplay implements Observe, DisplayElement{
    
    
    private float max = 0.0f;
    private float min = 200;
    private float sum = 0.0f;
    private int num = 0;
    private WeatherDate weatherDate;

    public StatisticsDisplay(WeatherDate weatherDate) {
    
    
        this.weatherDate = weatherDate;
        weatherDate.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
    
    
        sum += temp;
        num++;
        if (temp < min){
    
    
            min = temp;
        }
        if (temp > max){
    
    
            max = temp;
        }
        display();
    }
    @Override
    public void display() {
    
    
        System.out.println("Avg/Max/Min temperature = " + (sum / num)
                + "/" + max + "/" + min);
    }
}

Finally, the test

package Observer;

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

Test Results
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_36694674/article/details/107568932