一、基本概念
1、定义:
定义对象间的一种一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都能得到通知并被自动更新。
例如:天气预报服务,一旦你订阅该服务,,每天一旦有天气信息更新,它就会及时向你发送最新的天气信息。
2、结构图
- Subject:抽象被观察者,会将所有观察者对象保存到一个集合中,提供方法来添加和删除观察者。
- ConcreteSubject:具体被观察者,如自身发生改变,给所有注册的观察者发通知。
- Observer:抽象观察者,定义更新接口,如果接受到被观察者的通知后,自身进行更新。
- ConcreteObserver:具体观察者,实现更新接口
二、相关实例
定义天气作为被观察者,如果天气更新,观察者进行数据更新
1、Subject
/**
* 被观察者接口
*/
public interface Subject {
//注册观察者
void registObserver(Observer observer);
//取消注册
void unRegistObserver(Observer observer);
//通知观察者
void notifiObservers();
}
复制代码
2、Observer
/**
* 观察者接口
*/
public interface Observer<T> {
//数据更新
void update(T t);
}
复制代码
3、ConcreteSubject
public class Weather implements Subject {
private Vector<Observer> mObservers = new Vector<>();
public int mTemp;
@Override
public void registObserver(Observer observer) {
this.mObservers.add(observer);
}
@Override
public void unRegistObserver(Observer observer) {
this.mObservers.remove(observer);
}
@Override
public void notifiObservers() {
for (Observer observer : mObservers) {
observer.update(this);
}
}
/**
* 温度更新后,通知被观察者
* @param temp
*/
public void updateTemp(int temp){
this.mTemp = temp;
notifiObservers();
}
}
复制代码
4、ConcreteObserver
public class Forecast implements Observer<Weather>{
@Override
public void update(Weather weather) {
System.out.println("温度调整为:"+weather.mTemp);
}
}
复制代码
5、使用:
public class ObserverTest {
public static void main(String[] args){
Weather weather = new Weather();
Forecast forecast = new Forecast();
//注册观察者
weather.registObserver(forecast);
//被观察者数据有更新
weather.updateTemp(15);
}
}
复制代码
结果:
三、java.util.Observable源码解析
java中提供了Observerable和Observer相关实现类
1、java.util.Observable
public class Observable {
private boolean changed = false;
private final ArrayList<Observer> observers;
public Observable() {
observers = new ArrayList<>();
}
//添加观察者
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!observers.contains(o)) {
observers.add(o);
}
}
//删除观察者
public synchronized void deleteObserver(Observer o) {
observers.remove(o);
}
//通知观察者
public void notifyObservers() {
notifyObservers(null);
}
public void notifyObservers(Object arg) {
Observer[] arrLocal;
synchronized (this) {
//当changed为true的时候才通知观察者
if (!hasChanged())
return;
arrLocal = observers.toArray(new Observer[observers.size()]);
clearChanged();
}
for (int i = arrLocal.length - 1; i >= 0; i--)
arrLocal[i].update(this, arg);
}
public synchronized void deleteObservers() {
observers.clear();
}
//将changed设为true
protected synchronized void setChanged() {
changed = true;
}
//清除状态
protected synchronized void clearChanged() {
changed = false;
}
//查询状态
public synchronized boolean hasChanged() {
return changed;
}
public synchronized int countObservers() {
return observers.size();
}
}
复制代码
2、java.util.Observer
public interface Observer {
void update(Observable o, Object arg);
}
复制代码
3、实例调用:
(1)被观察者
public class Weather extends Observable {
public int mTemp;
/**
* 温度更新后,通知被观察者
* @param temp
*/
public void updateTemp(int temp){
this.mTemp = temp;
setChanged();
notifyObservers(this);
}
}
复制代码
(2)观察者
public class Forecast implements Observer {
@Override
public void update(Observable o, Object arg) {
if (arg instanceof Weather) {
System.out.println("温度调整为:"+((Weather) arg).mTemp);
}
}
}
复制代码
(3)使用
public class ObserverTest {
public static void main(String[] args) {
Weather weather = new Weather();
Forecast forecast = new Forecast();
weather.addObserver(forecast);
weather.updateTemp(20);
}
}
复制代码
结果:观察者接受到了通知并进行了更新