观察者模式定义
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
使用场景
杂志的发布订阅,微信公众号的通知等
设计原则
为了交互对象之间的松耦合设计而努力
优缺点
优点:
1、观察者和被观察者是抽象耦合的。
2、建立一套监听触发机制。
缺点:
1、如果观察者众多,通知所有的观察者会很消耗时间,这里建议异步处理。
2、可能出现循环调用。
UML类图

示例
这里应用《Head First设计模式》一书中的例子
主题(被观察者)接口
package com.study.headfirst.oberver;
/**
* 主题
*
* @author mdl
* @date 2019/12/02
*/
public interface Subject {
/**
* 注册观察者
*
* @param o
*/
public void registerObserver(Observer o);
/**
* 去除观察者
*
* @param o
*/
public void removeObserver(Observer o);
/**
* 通知所有观察者
*/
public void notifyObserver();
}
主题(被观察者):
package com.study.headfirst.oberver;
import java.util.ArrayList;
import java.util.List;
/**
* 被观察者
*
* @author mdl
* @date 2019/12/02
*/
public class WeatherData implements Subject {
/**
*记录观察者
*/
private List<Observer> os;
/**
*温度
*/
private float temp;
/**
*湿度
*/
private float humidity;
public WeatherData() {
os = new ArrayList<Observer>();
}
/* (non-Javadoc)
* @see com.study.headfirst.oberver.Subject#registerObserver(com.study.headfirst.oberver.Observer)
*/
@Override
public void registerObserver(Observer o) {
os.add(o);
}
/* (non-Javadoc)
* @see com.study.headfirst.oberver.Subject#removeObserver(com.study.headfirst.oberver.Observer)
*/
@Override
public void removeObserver(Observer o) {
int i = os.indexOf(o);
if (i > 0) {
os.remove(i);
}
}
/* (non-Javadoc)
* @see com.study.headfirst.oberver.Subject#notifyObserver()
*/
@Override
public void notifyObserver() {
for (Observer o : os) {
o.update(temp, humidity);
}
}
public void setMeasurements(float temp, float humidity) {
this.temp = temp;
this.humidity = humidity;
notifyObserver();
}
}
观察者A(当前状态布告板):
package com.study.headfirst.oberver;
/**
* 当前观测布告:显示温度
*
* @author mdl
* @date 2019/12/02
*/
public class CurrentConditionsDisplay implements DisplayElement, Observer{
private float temp;
public Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData =weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("当前状况-----当前温度:" + temp);
}
/* (non-Javadoc)
* @see com.study.headfirst.oberver.Observer#update(float)
*/
@Override
public void update(float temp, float humidity) {
// TODO Auto-generated method stub
this.temp =temp;
display();
}
}
观察者B(天气预报布告板):
package com.study.headfirst.oberver;
import com.study.headfirst.oberver.DisplayElement;
import com.study.headfirst.oberver.Observer;
/**
* 天气预报:显示温度、湿度
*
* @author mdl
* @date 2019/12/09
*/
public class ForcastDisplay implements DisplayElement, Observer{
private float temp;
private float humidity;
public Subject weatherData;
public ForcastDisplay(Subject weatherData) {
this.weatherData =weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("天气预报-----当前温度:" + temp + ", 当前湿度:" + humidity);
}
/* (non-Javadoc)
* @see com.study.headfirst.oberver.Observer#update(float)
*/
@Override
public void update(float temp, float humidity) {
// TODO Auto-generated method stub
this.temp =temp;
this.humidity =humidity;
display();
}
}
测试:
package com.study.headfirst.oberver;
/**
* 观察者模式
* 1. 主题的注册、移除、通知
* 2. 观察者接受通知后的动作
*
* @author mdl
* @date 2019/12/02
*/
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WeatherData subject =new WeatherData();
CurrentConditionsDisplay ccd =new CurrentConditionsDisplay(subject);
ForcastDisplay forcastDisplay =new ForcastDisplay(subject);
subject.setMeasurements(27f, 80f);
System.out.println("==================================");
subject.setMeasurements(35f, 60f);
}
}

来源:https://www.cnblogs.com/bloodthirsty/p/12010563.html