设计模式-观察者模式

80 阅读2分钟

设计模式-观察者模式

  • 来源于headfirst 设计模式第二章

代码及注解

public interface DisplayElement {
    public void display();
}
​
​
public interface Observer {
    public void update(float temp,float humidity, float pressure);
}
​
​
public interface Subject {
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObservers();
}
​
​
import java.util.ArrayList;
​
public class WeatherData implements Subject{
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;
​
    public WeatherData(){
        observers = new ArrayList();
    }
​
    public void registerObserver(Observer o){
        observers.add(o);
    }
​
    public void removeObserver(Observer o){
        int i  = observers.indexOf(o);
        if (i > 0 ){
            observers.remove(i);
        }
​
    }
​
    public void notifyObservers(){
        for(int i = 0; i < observers.size(); i++){
            Observer observer = (Observer) observers.get(i);
            observer.update(temperature,humidity,pressure);
        }
    }
​
    public void measurementsChanged(){
        notifyObservers();
    }
​
    public void setMeasurements(float temperature,float humidity,float pressure){
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}
​
​
​
import java.util.Observable;
​
public class WeatherData2 extends Observable {
​
    @Override
    public void notifyObservers() {
        super.notifyObservers();
    }
​
    @Override
    public void notifyObservers(Object arg) {
        super.notifyObservers(arg);
    }
}
​
​
public class CurrentConditionsDisplay implements Observer,DisplayElement{
    private float temperature;
    private float humidity;
    private Subject weatherData;
​
    public CurrentConditionsDisplay(Subject weatherData){
        this.weatherData = weatherData; //
        weatherData.registerObserver(this); // 注册observer同时包括了this.weatherData不会有问题吗
    }
​
    @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 + "% humdidity");
    }
}
/*
这里实现了两个接口Observer,DisplayElement
​
我的理解是接口隔离原则,observer只负责作为订阅者,订阅者必须知道主题是谁,所以在初始化订阅者是要传入主题,同时主题要需要订阅者
所以主题提供了两个方法registerObserver和removeObserver来让订阅者注册。
​
主题者知道订阅者是通过registerObserver来达成
而Observer知道主题是通过类构造传进主题对象
​
订阅者接收通知是通过update方法,而展示是通过display.这两个分成两个接口,因为diplay是属于展示,展示形式可能多样,根据单一原则接口最小化
隔离原则把display分到另一个接口里。
​
代码写到这里,还有一个问题点是,setmetaurement和update的参数是强耦合的
​
​
关于主题对订阅者的通知,在这里主要是update
​
当然书中还有一个例子,就是在主题变更时,update函数,传入主题对象给Observer(订阅者),让订阅者来主动通过主题对象拉并且展示
​
但这随之而来的是当主题会被阻塞在订阅者拉数据和展示数据
 */
 
 
 
 public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherdata = new WeatherData();
        CurrentConditionsDisplay CurrentDisplay = new CurrentConditionsDisplay(weatherdata);
        weatherdata.setMeasurements(80,65,30.4f);
        weatherdata.setMeasurements(82,70,29.2f);
        weatherdata.setMeasurements(78,90,29.2f);
    }
}
​