本系列主要是《head first 设计模式》的阅读笔记以及实验结果
观察者模式
观察者模式定义了一些列对象之间的一对多的关系;当一个对象改变状态,其他依赖的对象都会收到通知。
认识观察者模式
我们先看看报纸和杂志的订阅是怎么回事:
1.报社的业务就是出版报纸。
2.向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订阅用户,就会一致收到新报纸。
3.当你不想再看报纸的时候,取消订阅,他们就不再送新的报纸来。
4.主要报社还在运营,就会一直有人(或单位)向他们订阅报纸或者取消订阅报纸。
在这里,出版者可以映射为“主题”(Subject),订阅者可以映射为“观察者”(Observer).
主题和观察者定义了一对多的关系。观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知。根据通知的风格,观察者可能因此新值而更新。实现观察者模式有很多种途径,但是以包含Subject和Observer接口的类设计的做法最为常见。
观察者模式实例
设计原则:为了交互对象之间的松耦合设计而努力。
Subject接口:
package com.njust.chaptertwo;
/**
* 主题接口,负责管理“观察者”:注册、移除、通知
* @author Administrator
*
*/
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
Observer接口:
package com.njust.chaptertwo;
/**
* 观察者接口
* @author Administrator
*
*/
public interface Observer {
public void update(float temperature, float humidity, float pressure);
}
WeatherData对象:实现Subject接口
package com.njust.chaptertwo;
import java.util.ArrayList;
public class WeatherData implements Subject {
//温度
private float temperature;
//湿度
private float humidity;
//气压
private float pressure;
//观察者们
private ArrayList observers;
//构造函数
public WeatherData(){
observers = new ArrayList();
}
public float getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public ArrayList getObservers() {
return observers;
}
public void setObservers(ArrayList observers) {
this.observers = observers;
}
public void registerObserver(Observer o) {
// 注册
observers.add(o);
}
public void removeObserver(Observer o) {
// 移除:先判断是否在观察者列表里
int i = observers.indexOf(o);
if(i>=0){
observers.remove(i);
}
}
// 通知
public void notifyObservers() {
for(int i=0;i<observers.size();i++){
Observer observer = (Observer)observers.get(i);
observer.update(temperature, humidity, pressure); }
}
//气象站数据更新时,通知所有观察者
public void measurementsChanged(){
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
CurrentConditionDisplay对象:实现Observer接口
package com.njust.chaptertwo;
/**
* 根据WeatherData对象显示当前的观测值
* @author Administrator
*
*/
public class CurrentConditionDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void display() {
System.out.println("Current condition: " + temperature +"F degrees and " + humidity +"% humidity");
}
public void update(float temperature, float humidity, float pressure) {
this.humidity = humidity;
this.temperature = temperature;
display();
}
DisplayElement接口,体现面向接口的编程
package com.njust.chaptertwo;
/**
* 布告板的统一接口
* @author Administrator
*
*/
public interface DisplayElement {
//布告板显示
public void display();
}
测试类
package com.njust.chaptertwo;
public class WeatherStation {
/**
* @param args
*/
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 56, 33.5f);
}
}
java内置的的观察者模式
java api有内置的观察者模式–java.util中的包含基本的Observer接口与Observer类。