观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并更新。
观察者分为主题,观察者对象。
public interface Subject{
public void registerObserver(Observer o);//注册观察者
public void removeObserver(Observer o);//删除观察者
public void notifyObservers();//通知观察者
}
public interface ObServer{
public void update();//所有的观察者都必须实现update方法,以实现观察者接口。
}
气象站例子:温度改变更新每一个布告栏(观察者)。
主题:
public class WeatherData implements Subject{
private float temperature;
private float humidity;
private float pressure;
private List<Observer> obersers; //保存添加的观察者对象
public WeatherData(){
obersers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o){
obersers.add(o);
}
@Override
public void removeObserver(Observer o){
obersers.remove(o);
}
@Override
public void notifyObservers(){
for(Observero : observers){
o.update(temperature,humidity,pressure);//更新注册的观察者对象
}
}
public void measurementsChanged(){
notifyObservers();
}
/**
得到天气情况,测试用。也可实际抓取
*/
public void setMeasuremetns(float tmperature,float humidity,float pressure){
this.tmperature = tmperature;
this.humidity = humidity;
this.pressure = pressure;
mesurementsChanged();
}
}
观察者:
public class CurrentConditionsDisplay implemens Observer,DisplayElement{
private float temperature;
private Subject weatherData;//保存主题,删除观察者对象时可用
public CurrentConditionsDisplay(Subject weatherData){
this.weatherData= weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temperature,float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
}
@Override
public void display(){
System.out.println("温度:"+temperature);
}
}
启动气象站
public class WeatherStation{
public static void main(String[] str){
WeatherData weaterDate = new WeatherData();//新建一个主题
CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weaterDate );
weaterDate.setMesurement(80,65,30.4f);//改变温度
}
}
使用java内置的观察者模式
利用java内置的支持重做气象站
主题:继承Observable类
public class WeatherData extends Observable{
private float temperature;
private float humidity;
private float pressure;
public WeaterData(){
}
public setMesurements(float temperature,float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
mesurementsChanged();
}
public float getTemperature(){
return temperature;
}
public float getHumidity(){
return humidity ;
}
public float getPressure(){
return pressure;
}
public mesurementsChanged(){
setChanged();
notifyObersers();//用拉的方式
}
}
观察者:实现Observer
public class CurrentConditionDisplay implements Observer,DisplayElements{
private Observal weatherData;
private float temperature;
private humidity;
public CurrentConditionDisplay(Observal observal){
this.weatherData = observal;
weatherData.addObserver(this);
}
@Override
public void update(Observal weatherData,Object arg){
if(weatherData instanceof WeatherDate){
this.weatherDate = weatherData;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
display();
}
}
@Override
public void display(){
System.out.println("温度:"+tmeperature +"/r/n");
}
}
在JDK中,并非只有在java.util包中才能找到观察者模式,在JavaBeans和Swing中,也都实现了观察者模式。