一、简介
观察者模式是对象间多对一依赖的一种设计方案,被依赖的对象称为Subject,依赖的对象为Observer,Subject通知Observer发生的变化。
相关设计类图如下:
二、实现
1)Subject
package com.giser.designpattern.observer;
/**
* @Note {接口}
* @author giserDev
* @Date 2020-06-07 19:59:52
*/
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
2) Observer
package com.giser.designpattern.observer;
/**
* @Note {观察者接口}
* @author giserDev
* @Date 2020-06-07 19:57:42
*/
public interface Observer {
void update(float temperature, float pressure, float humidity);
}
3) 核心类
package com.giser.designpattern.observer;
import java.util.ArrayList;
/**
* @Note {核心类
* 1、包含天气情况信息和观察者集合;
* 2、数据更新时,通过集合通知所有观察者。
* }
* @author giserDev
* @Date 2020-06-07 20:01:31
*/
public class WeatherData implements Subject {
private float temperature;
private float pressure;
private float humidity;
private ArrayList<Observer> observerList;
public WeatherData() {
observerList = new ArrayList<>();
}
/**
* @Note {更新数据信息}
* @author giserDev
* @Date 2020-06-07 20:15:41
*/
public void updateWeatherData(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
// 推送数据更新
notifyObservers();
}
/**
* 注册观察者
*/
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
/**
* 移除观察者
*/
@Override
public void removeObserver(Observer observer) {
if (observerList.contains(observer)) {
observerList.remove(observer);
}
}
/**
* 通知所有观察者
*/
@Override
public void notifyObservers() {
for (Observer observer : observerList) {
observer.update(temperature, pressure, humidity);
}
}
public float getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
public ArrayList<Observer> getObserverList() {
return observerList;
}
public void setObserverList(ArrayList<Observer> observerList) {
this.observerList = observerList;
}
}
4) 观察者
package com.giser.designpattern.observer;
public class CurrentCondition implements Observer {
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
private void display() {
System.out.println("***Today mTemperature: " + temperature + "***");
System.out.println("***Today mPressure: " + pressure + "***");
System.out.println("***Today mHumidity: " + humidity + "***");
}
}
5) 测试
package com.giser.designpattern.observer;
/**
* @Note {客户端}
* @author giserDev
* @Date 2020-06-07 20:11:23
*/
public class Client {
public static void main(String[] args) {
// 创建WeatherData,用于观察者的注册、移除、通知等
WeatherData weatherData = new WeatherData();
// 创建观察者
CurrentCondition currentCondition = new CurrentCondition();
// 将观察者注册到WeatherData
weatherData.registerObserver(currentCondition);
// 测试通知
weatherData.updateWeatherData(10f, 99.0f, 28.8f);
}
}
当需要添加新的观察者时,只需直接注册即可。
package com.giser.designpattern.observer;
public class Sina implements Observer {
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
private void display() {
System.out.println("***Sina mTemperature: " + temperature + "***");
System.out.println("***Sina mPressure: " + pressure + "***");
System.out.println("***Sina mHumidity: " + humidity + "***");
}
}
客户端
package com.giser.designpattern.observer;
/**
* @Note {客户端}
* @author giserDev
* @Date 2020-06-07 20:11:23
*/
public class Client {
public static void main(String[] args) {
// 创建WeatherData,用于观察者的注册、移除、通知等
WeatherData weatherData = new WeatherData();
// 创建观察者
CurrentCondition currentCondition = new CurrentCondition();
Sina sina = new Sina();// 添加新的观察者
// 将观察者注册到WeatherData
weatherData.registerObserver(currentCondition);
weatherData.registerObserver(sina);// 注册新的观察者
// 测试通知
weatherData.updateWeatherData(10f, 99.0f, 28.8f);
}
}
三、说明
1)观察者模式以集合的方式管理Observer,包括注册、移除和通知等,遵守了OCP原则。
2)在JDK中的java.util.Observable类中使用了观察者模式:
public class Observable {
private boolean changed = false;
private Vector<Observer> obs;
/** Construct an Observable with zero Observers. */
public Observable() {
obs = new Vector<>();
}
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
public void notifyObservers() {
notifyObservers(null);
}
public void notifyObservers(Object arg) {
// 省略部分代码
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
/**
* Clears the observer list so that this object no longer has any observers.
*/
public synchronized void deleteObservers() {
obs.removeAllElements();
}
// 省略部分代码
}