观察者模式,在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。
1、代码结构:
package observer; /** * 观察者接口 */ public interface Observer { /** * 当气象观测值改变时,主题会把这些状态值当作方法的参数,传递给观察者 * @param temp 温度 * @param humidity 湿度 * @param pressure 气压 */ public void update(float temp, float humidity, float pressure); }
package observer; /** * 布告板 */ public interface DisplayElement { /** * 当布告板需要显示时,调用此方法 */ public void display(); }
package observer; /** * 主题 */ public interface Subject { /** * 注册一个观察者 * @param o */ public void registerObserver(Observer o); /** * 删除一个观察者 * @param o */ public void removeObserver(Observer o); /** * 当主题改变的时,这个方法会被调用,以通知所有的观察者 */ public void notifyObservers(); }
package observer; import java.util.ArrayList; /** * 天气数据推送 */ public class WeatherData implements Subject{ private ArrayList<Observer> observers;//观察者们 private float temperature;//温度 private float humidity;//湿度 private float pressure;//气压 public WeatherData(){ observers = new ArrayList<Observer>(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { observers.remove(0); } @Override public void notifyObservers() { for(Observer o : observers){ //推送给观察者们 o.update(temperature, humidity, pressure); } } //检测改变 public void measurementsChanged(){ notifyObservers(); } //也可以让观察者自己来取 public ArrayList<Observer> getObservers() { return observers; } //也可以让观察者自己来取 public float getTemperature() { return temperature; } //也可以让观察者自己来取 public float getPressure() { return pressure; } public void setMeasurements(float temperature, float humidity, float pressure){ this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } }
package observer; public class CurrentConditionsDisplay implements Observer, DisplayElement{ private float temperature;//温度 private float humidity;//湿度 private float pressure;//气压 private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void update(float temp, float humidity, float pressure) { this.temperature = temp; this.humidity = humidity; this.pressure = pressure; this.display(); } @Override public void display() { System.out.println("Current conditions:"+temperature +"#" + humidity +"#"+ pressure); } }
package observer; /** * 气象站 */ public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80, 65, 78); weatherData.setMeasurements(11, 111, 1111); weatherData.setMeasurements(22, 222, 222); } /** * 运行结果: * Current conditions:80.0#65.0#78.0 Current conditions:11.0#111.0#1111.0 Current conditions:22.0#222.0#222.0 */ }
java也有内置的观察者模式,但是这边是使用观察者去拉数据的方式,而不是把数据推给观察者
源代码很少,可以去翻阅查询,在java.util包下面
1、代码结构:
package observer1; /** * 布告板 */ public interface DisplayElement { /** * 当布告板需要显示时,调用此方法 */ public void display(); }
package observer1; import java.util.Observable; /** * 天气数据,继承了‘可观察者’类 */ public class WeatherData extends Observable{ private float temperature;//温度 private float humidity;//湿度 private float pressure;//气压 //检测改变 public void measurementsChanged(){ setChanged();//设置已经改变,这样的手动设置可以控制信息的手动推送 notifyObservers(); } 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 getPressure() { return pressure; } //也可以让观察者自己来取 public float getHumidity() { return humidity; } }
package observer1; import java.util.Observable; import java.util.Observer; /** * 显示当前的气象信息 */ public class CurrentConditionsDisplay implements Observer,DisplayElement{ Observable observable;//可观察者 private float temperature;//温度 private float humidity;//湿度 private float pressure;//气压 public CurrentConditionsDisplay(Observable observable){ this.observable = observable; observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if(o instanceof WeatherData){ WeatherData weatherData = (WeatherData) o; //从气象数据中进行取得数据 this.temperature = weatherData.getTemperature(); this.humidity = weatherData.getHumidity(); this.pressure = weatherData.getPressure(); display(); } } @Override public void display() { System.out.println("Current conditions:"+temperature +"#" + humidity +"#"+ pressure); } }
package observer1; /** * 气象站 */ public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80, 65, 78); weatherData.setMeasurements(11, 111, 1111); weatherData.setMeasurements(22, 222, 222); } /** * 运行结果: * Current conditions:80.0#65.0#78.0 Current conditions:11.0#111.0#1111.0 Current conditions:22.0#222.0#222.0 */ }