简介:
观察者模式是JDK中最多的设计模式之一,非常有用,观察者模式介绍了一对多的依赖关系及松耦合,有了观察者,你将会消息灵通。
认识观察者模式,看一个报纸、杂志订阅是怎么回事:
(1). 报社的业务就是出版报纸。
(2). 向某家报社订阅报纸,只要他们有新的报纸,就会给你送来,只要你是他们的订户,你就会一直收到新报纸。
(3). 当你不想再看报纸的时候,取消订阅,他们就不会再送来新报纸来。
(4). 只要报社还在运营,就会一直有人向他们订阅报纸或取消报纸。
出版社 + 订阅者 = 观察者模式
1. 定义:
观察者模式定义了一对多依赖,这样一来,当一个对象发生改变状态时,它的所有依赖者都跟着收到通知并自动更新。
2. 设计原则:
为了交互对象之间的松耦合设计而努力
松耦合的好处:当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。
3. 代码实现:
3.1 首先我们先定义
观察者主题接口
package com.chengzhang.subject;
/**
* 主题接口
* @author Administrator
*/
public interface Subject {
/**
* 注册观察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 移除观察者
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知观察者
*/
public void notifyObservers();
观察者接口
package com.chengzhang.subject;
/**
* 观察者接口
* @author Administrator
*/
public interface Observer {
/**
* 更新数据
* @param temp
* @param humidity
* @param pressure
*/
public void update(float temp, float humidity, float pressure);
}
3.2 然后我们实现以上接口
实现主题接口
package com.chengzhang.subject.impl;
import java.util.ArrayList;
import java.util.List;
import com.chengzhang.subject.Observer;
import com.chengzhang.subject.Subject;
public class WeatherData implements Subject {
// 存放观察者对象
private List<Observer> observersList;
private float temperature;
private float humidity;
private float pressure;
public WeatherData(){
observersList = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer observer) {
observersList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int index = observersList.indexOf(observer);
if(index >= 0){
observersList.remove(index);
}
}
@Override
public void notifyObservers() {
for(int i=0; i<observersList.size(); i++){
Observer observer = observersList.get(i);
observer.update(temperature, humidity, pressure);
}
}
/**
* 天气发生变化会自动调用该方法
*/
public void measurementsChanged(){
notifyObservers();
}
/**
* 假设天气发生变化
* @param temperature
* @param humidity
* @param pressure
*/
public void setMeasurements(float temperature, float humidity, float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
实现布告板接口
package com.chengzhang.subject.impl;
import com.chengzhang.subject.Observer;
import com.chengzhang.subject.Subject;
public class CurrentConditionsDisplay implements Observer {
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;
public CurrentConditionsDisplay(WeatherData weatherData){
this.weatherData = weatherData;
this.weatherData.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
public void display(){
System.out.println("当前温度:" + this.temperature);
System.out.println("当期湿度:" + this.humidity);
System.out.println("当期气压:" + this.pressure);
}
}
4. 观察者模式测试
package com.chengzhang.subject.impl;
public class WeatherStation {
public static void main(String[] args) {
// 创建主题对象
WeatherData weatherData = new WeatherData();
// 创建观察者对象并注册
CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
// 天气发生变化
weatherData.setMeasurements(12.44f, 23.12f, 22);
}
}
4.1 输出结果
当前温度:12.44
当期湿度:23.12
当期气压:22.0