出版者+订阅者=观察者模式
观察者模式就像报纸订阅一样,出版者称为“主题”(subject)。订阅者称为“观察者”(observe)。
观察者订阅主题,当主题内的数据改变时就会通知观察者,观察者就会收到更新。
观察者模式定义了对象之间的一对多依赖,这样当一个对象改变状态时,他的依赖者都会收到通知和自动更新
观察者模式类图:
观察者模式案例:
下面我们要实现一个小型的气象站和布告板,气象站更新当前的气象信息,布告板显示当前信息
气象站设计图:
代码:
package com.wdf.observer;
/*
* 主题接口
* */
public interface Subject {
public void registerObserver(Observer o);//注册观察者
public void removeObserver(Observer o);//移除观察者
public void notifyObserver();//当主题状态发生改变时,通知所有观察者
}
package com.wdf.observer;
/*
* 观察者接口
* */
public interface Observer {
public void update(float temp,float humidity,float pressure);
}
package com.wdf.observer;
public interface DisplayElement {
public void display();//布告板显示时调用此方法
}
package com.wdf.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) {
int i=observers.indexOf(o);
if(i>=0)
observers.remove(i);
}
@Override
public void notifyObserver() {
//通知观察者更新
for(Observer o:observers){
//遍历出观察者对象,调用他的update
o.update(temperature, humidity, pressure);
}
}
public void measurementsChanged(){
notifyObserver();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
measurementsChanged();//数据更新了
}
}
package com.wdf.observer;
/*
* 目前状况布告板
* */
public class CurrentConditionDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;//用于以后取消注册
public CurrentConditionDisplay(Subject weatherData) {
this.weatherData=weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("temperature="+temperature+"humidity="+humidity+"pressure="+pressure);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature=temp;
this.humidity=humidity;
this.pressure=pressure;
display();
}
public void unRegister(){
weatherData.removeObserver(this);
}
}
package com.wdf.observer;
/*
* 目前状况布告板
* */
public class CurrentConditionDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;//用于以后取消注册
public CurrentConditionDisplay(Subject weatherData) {
this.weatherData=weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("temperature="+temperature+"humidity="+humidity+"pressure="+pressure);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature=temp;
this.humidity=humidity;
this.pressure=pressure;
display();
}
public void unRegister(){
weatherData.removeObserver(this);
}
}
package com.wdf.observer;
/*
* 测试类
* */
public class test {
public static void main(String[] args) {
WeatherData weatherData=new WeatherData();
CurrentConditionDisplay conditionDisplay=new CurrentConditionDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
conditionDisplay.unRegister();
}
}