观察者模式是在数据发生变化的时候,能及时捕捉变化并进行相关操作,适用场景有监测天气变化
interface Subject {
public void registerObserver(Observer o); //数据源提供用于(观察者想要获取数据源时调用此方法注册)
public void removeObserver(Observer o); //数据源提供用于(观察者不再需要数据源数据时,退出注册)
public void notifyObservers(); //数据源向注册在案的所有观察者发送数据
}
interface DisplayElement {
public void display(); //观察者调用此方法向用户显示数据
}
interface Observer {
public void update(double temp, double humidity, double pressure);
//观察者当接收到来自数据源的信息时,调用此方法更新自身数据
}
/**
* 天气数据
*/
class WeatherData implements Subject {
private ArrayList observers;
private double temperature; //温度
private double humidity; //湿度
private double pressure; //气压
/*当数据源初始化时,维护一个记录观察者的列表*/
public WeatherData() {
observers = new ArrayList();
}
/*实现Subject接口的注册方法*/
public void registerObserver(Observer o) {
observers.add(o);
}
/*实现Subject接口的取消注册方法*/
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) observers.remove(i);
}
/*实现Subject接口的notifyObservers(),用于向所有注册的观察者发送数据*/
public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer) observers.get(i);
observer.update(temperature, humidity, pressure);
//更新数据,该操作会调用ConditionDisplay类的update方法
}
}
/*当有新数据时,向注册的观察者发送数据*/
public void measurementsChanged() {
notifyObservers();
}
/*向获取数据的设备提供接口
当气象观察站获得新数据
会调用此接口向WeatherData写数据
以便WeatherData向观察者发送数据*/
public void setMeasurements(double temp, double humditidy, double pressure) {
this.temperature = temp;
this.humidity = humditidy;
this.pressure = pressure;
measurementsChanged(); //表示有了新数据
}
}
class ConditionDisplay implements Observer,DisplayElement{
private double temperature;
private double humidity;
private double pressure;
private String name;
private Subject weatherdata; //观察者也要维护一个中介(WeatherData)作为数据源
//当观察者初始化时,需要指定数据源和观察者的名字
public ConditionDisplay(Subject weatherdata,String name) {
this.name = name;
this.weatherdata = weatherdata;//接收天气数据
weatherdata.registerObserver(this);//注册当前观察者实例
//向数据源注册,代表需要从数据源获取数据
}
//把数据打印给用户
public void display() {
System.out.println("Observer "+name+" data:");
System.out.println("temperature: "+temperature);
System.out.println("humidity: "+humidity);
System.out.println("pressure: "+pressure);
System.out.println();
}
/*当从数据源(WeatherData)获得数据后,用新数据更新自身数据*/
public void update(double temp, double humidity, double pressure) {
this.temperature = temp;
this.humidity = humidity;
this.pressure = pressure;
display();//信息更新完后,自动打印
}
}
class WeatherStation {
public static void main(String[] args) {
WeatherData weatherdata = new WeatherData();
ConditionDisplay cd1 = new ConditionDisplay(weatherdata, "ob1");
// ConditionDisplay cd2 = new ConditionDisplay(weatherdata, "ob2");
// ConditionDisplay cd3 = new ConditionDisplay(weatherdata, "ob3");
/*数据源获得数据,并调用WeatherData的方法,来向WeatherData 写数据*/
weatherdata.setMeasurements(10.5, 10.4, 10.8);
weatherdata.setMeasurements(10.4, 10.1, 10.2);
}
}
下面是Java已经写好的观察者类
//Java自定义类
interface DisplayElement {
public void display(); //观察者调用此方法向用户显示数据
}
//天气数据
class WeatherData extends Observable{
private double temperature;
private double humidity;
private double pressure;
WeatherData() {}
//向观察者发送数据
public void measurementsChanged() {
setChanged(); //向观察者发送数据之前必须先调用这个,表示数据已经更新,change=true
notifyObservers(); //个人认为notifyObservers()会自动调用ConditionDisplay类的update()方法
}
//从数据源收到数据后,是先更新自己的数据,再把数据发给观察者
void setMeasurements(double temp,double humidity,double pressure) {
this.temperature = temp;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
//留出接口给观察者获取数据
double getTemperature() {
return temperature;
}
double getHumidity() {
return humidity;
}
double getPressure() {
return pressure;
}
}
class ConditionDisplay implements Observer,DisplayElement{
private double temperature;
private double humidity;
private double pressure;
private Observable observable;//任何数据源的引用
//当构建观察者时,必须指定其 数据源
ConditionDisplay(Observable observable,String name) {
this.observable = observable;
observable.addObserver(this);//注册
}
public void display() {
System.out.println("temperature:"+temperature+" humidity:"+humidity+" pressure:"+pressure);
}
//更新方法,
public void update(Observable o, Object arg) {
if(o instanceof WeatherData) {
WeatherData w = (WeatherData)o;//向下转型调用天气数据类的方法
this.temperature = w.getTemperature();
this.humidity = w.getHumidity();
this.pressure = w.getPressure();
display();//展示数据
}
}
}
class WeatherStation {
public static void main(String[] args) {
/*数据源和观察者都要维护一个 中介角色WeatherData*/
WeatherData weatherdata = new WeatherData();
ConditionDisplay cd1 = new ConditionDisplay(weatherdata,"ob1");
/*数据源获得数据,并调用WeatherData的方法,来向WeatherData 写数据*/
weatherdata.setMeasurements(10.5, 10.4, 10.8);
weatherdata.setMeasurements(10.2, 10.1, 10.6);
}
}
参考博文:https://blog.csdn.net/u014453898/article/details/79167927