设计模式之观察模式
一:介绍
定义:定义了对象之间一对多依赖,这样一来,当对象改变状态的时候,他所有依赖者都会接受到通知并自动更新。观察者模式属于行为型模式。
二:设计原则
原则:为了交互对象之间的松耦合设计而努力。
三:实战
案例:天气预报。此处就直接引用head first的案例
主题接口:
public interface Subject {
/**
* 注册需要通知的观察者
* @param o
*/
public void refisterObserver(Observer o);
/**
* 移除观察者
* @param o
*/
public void removeObervers(Observer o);
/**
* 通知所有注册的观察者
*/
public void notifyObservers();
}
观察者接口:
public interface Observer {
/**
* 更新布告板功能
* @param temp
* @param humidity
* @param pressure
*/
public void update(float temp, float humidity, float pressure);
}
抽离布告板的展示接口:
public interface DisplayElement {
/**
* 布告板信息的展示
*/
public void display();
}
气象台数据的实现:
public class WeatherData implements Subject {
/**
* 布告板集合
*/
private ArrayList<Observer> observerList = new ArrayList<>();
/**
* 温度
*/
private float tempearture;
/**
* 湿度
*/
private float humidity;
/**
* 压强
*/
private float pressure;
@Override
public void refisterObserver(Observer o) {
if (!observerList.contains(o)) {
observerList.add(o);
} else {
System.out.println("此布告板以注册!");
}
}
@Override
public void removeObervers(Observer o) {
if (observerList.contains(o)) {
observerList.remove(o);
} else {
System.out.println("无此布告板");
}
}
@Override
public void notifyObservers() {
for (Observer observer : observerList) {
observer.update(tempearture, humidity, pressure);
}
}
/**
* 通知观察者
*/
public void measurementChanged() {
notifyObservers();
}
/**
* 此处用来测试天气更改
* @param tempearture
* @param humidity
* @param pressure
*/
public void setMeasurements(float tempearture, float humidity, float pressure) {
this.tempearture = tempearture;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
}
用以展示当前气象的布告板:
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay() {
}
/**
* 将布告板注册到气象台
* @param weatherData
*/
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.refisterObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.println("Current conditions:" + temperature + " F degrees and " + humidity + "%humdity");
}
}
气象台:
public class WeatherStation {
public static void main(String[] args) {
//初始化一个容器用来存储布告板
WeatherData weatherData = new WeatherData();
//将布告板存储到容器中
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(81, 67, 32.4f);
weatherData.setMeasurements(85, 63, 32.5f);
}
}
四:总结
观察者的优点也是很明显的。观察者和被观察者之间是抽象耦合的。通过建立一套触发机制就可以通知到所有的观察者。
同时,缺点也比较明显,如果观察者数量较多且对话内容较长,会耗时比较长的时间。观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。