观察者模式主要是为了降低对象之间的耦合度
在对象之间定义一对多的依赖,当一的一方状态发生改变的时候,依赖一的一方(多的一方)就会收到通知,并进行自动更新
此时up主就是被观察者,而订阅的人就是观察者,一旦被观察者(主题)状态发生改变,相应的观察者也就会就行改变
经典问题:气象站问题
当气象站监测的温度、湿度、压强等信息发生改变时,相应的看板也要发生信息的改变
代码实现
public interface Subject { //主题,也就是被观察者
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver();
}
//气象台
public class WeatherData implements Subject{
private float temperature;
private float humidity;
private float pressure;
private List<Observer> observers;
public WeatherData() {
this.observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
Iterator<Observer> iterator = observers.iterator();
while (iterator.hasNext()){
Observer next = iterator.next();
if(next.equals(observer)){
iterator.remove();
break;
}
}
}
@Override
public void notifyObserver() {
for (Observer observer : observers) {
observer.update(temperature,humidity,pressure);
}
}
public void measurementsChanged(){
notifyObserver();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
//观察者接口
public interface Observer {
void update(float temp,float humidity,float pressure); //发生变化时调用的方法
}
//面板
public class CurrentConditionsDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private Subject subject;
//注册
public CurrentConditionsDisplay(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void display() {
System.out.println("当前天气面板:温度:"+temperature+" 湿度:"+humidity);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
}
- 当气象台的监测到温度发生变化时,调用
measurementsChanged方法,主题会推送数据到观察者,并调用观察者发生数据变化后进行的操作 - 当前的观察者方法是采用推送数据给观察者,也可采用观察则自己拉去的方法
- jdk有内置的观察者模式
jdk观察者模式源码分析
public class Observable {
private boolean changed = false;//判断是否改变,可进行控制
private Vector<Observer> obs;
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) {
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
public synchronized void deleteObservers() {
obs.removeAllElements();
}
protected synchronized void setChanged() {
changed = true;
}
protected synchronized void clearChanged() {
changed = false;
}
public synchronized boolean hasChanged() {
return changed;
}
public synchronized int countObservers() {
return obs.size();
}
}
//观察者接口
public interface Observer {
//o为被观察者对象,可以拉去数据
//arg是推送过来的数据
void update(Observable o, Object arg);
}