观察者模式,在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。
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
*/
}