觀察者模式:定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知並更新。
觀察者分爲主題,觀察者對象。
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中,也都實現了觀察者模式。