观察者模式的定义:定义了对象之间的一对多依赖,当一个对象改变时,它的所有依赖者都会收到通知并自动更新。
java源码中观察者模式以推和拉来传送数据。
这个类代表一个观察者对象或者是模型-视图范式中的数据。对象想被其他对象观察可以继承这个类。
一个可以被观察的对象可以有一个或多个的观察者(一对多)。
一个观察者可能是任何实现Observer接口的对象。
当一个被观察者实例改变之后,应用程序会调用Observable的notifyObservers方法导致所有的观察者调用自己的update方法做相应的改变。
通知传递的顺序是没有明确指定的。
默认实现提供被观察者类将会以它们注册兴趣顺序来通知的,但是子类可以改变这个顺序,当你在其他子线程中传递通知时,不确保传递顺序,或者是可能确保子类按照它们选
择的顺序。
java源码中的被观察者code:
public class Observable {
private boolean changed = false;
private Vector<Observer> obs;
public Observable() {
obs = new Vector<>();
}
/**
* 加入观察者
* @param o 一个要被加入的观察者对象.
* @throws NullPointerException 如果是null的.
*/
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/**
* 移除观察者
* @param o the observer to be deleted.
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
/**
* 如果这个对象改变了,会通过hasChanged方法来表明的,接着通知所有的观察者之后又调用clearChanged方法表明该对象不再改变了。
* 每个观察者有自己的update带有两个参数的方法(参数:Observable object,null).
* 换句话说,该方法等同于notifyObservers(null)
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* 通知观察者们,此参数根据客户端需求来传递
*/
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
/* 两大潜在竞争条件的缺点:
* 1)最新增加的观察者可能错失这次的通知进程
* 2) 最新移除观察者可能接收到通知
*/
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;
}
/**
* 返回观察者的个数
* @return 观察者的个数
*/
public synchronized int countObservers() {
return obs.size();
}
}
观察者,最主要的职责就是根据被观察者给的东西来进行自己的操作,所以抽象为一个接口,具体的观察者都要实现这个接口
java源码中观察者code:
/**
* 当一个类想要被通知被观察者对象的改变时,可以实现这个接口
*/
public interface Observer {
/**
* 被观察者改变时这个方法会被调用,我们要重写这个方法,根据我们的业务需求来编写不同的代码
*
* @param o 被观察的对象,因为被观察的对象也不明确观察者们具体要的是什么东东,所以就把自己传递给所有的观察者.让观察者自己来获取自己感兴趣的。
* @param arg .
*/
void update(Observable o, Object arg);
}接下来就是例子
一个天气可观察者,三个观察对象
可观察的对象:
import java.util.Observable;
public class WeatherObservable extends Observable {
/** 温度 */
private float temperature;
/** 湿度 */
private float moisture;
/** 气压 */
private float pressure;
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public float getTemperature() {
return temperature;
}
public float getMoisture() {
return moisture;
}
public void setMoisture(float moisture) {
this.moisture = moisture;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public void setProperity(float pressure, float moisture, float temperature) {
this.pressure = pressure;
this.moisture = moisture;
this.temperature = temperature;
}
/** 设置为改变了 */
public void setChanged() {
super.setChanged();
}
}
三个观察者:
观察湿度:
import java.util.Observable;
import java.util.Observer;
/** 观察温度 */
public class WatchTemperature implements Observer {
@Override
public void update(Observable o, Object arg) {
if (o instanceof WeatherObservable) {
float temperature = ((WeatherObservable) o).getTemperature();
System.out.println("温度改变为:" + temperature);
}
}
}
import java.util.Observable;
import java.util.Observer;
/** 监听湿度 */
public class WatchMoisture implements Observer {
@Override
public void update(Observable o, Object arg) {
if (o instanceof WeatherObservable) {
float moisture = ((WeatherObservable) o).getMoisture();
System.out.println("湿度改变为" + moisture);
}
}
}
import java.util.Observable;
import java.util.Observer;
/** 对气压感兴趣 */
public class WatchPressure implements Observer {
@Override
public void update(Observable o, Object arg) {
if (o instanceof WeatherObservable) {
float pressure = ((WeatherObservable) o).getPressure();
System.out.println("气压改变了" + pressure);
}
}
}
测试类:
/** 测试类 */
public class Test {
public static void main(String[] args) {
WeatherObservable ob = new WeatherObservable();
WatchTemperature watchTemperature = new WatchTemperature();
WatchMoisture watchMoisture = new WatchMoisture();
WatchPressure watchPressure = new WatchPressure();
ob.addObserver(watchMoisture);
ob.addObserver(watchPressure);
ob.addObserver(watchTemperature);
ob.setChanged();
ob.setProperity(120, 30, 20);
ob.notifyObservers();
}
}
结果:
2430

被折叠的 条评论
为什么被折叠?



