观察者模式是一种常见的设计模式,顾名思义有观察者与被观察者,被观察者的状态有变动会通知观察者,观察者会收到通知,进而做进一步的操作
要实现观察者模式我们要首先思考下面几个问题:
1. 观察者的实现
2. 被观察者的实现
3. 被观察者状态变更是怎么通知观察者
4. 观察者收到通知如何处理接下来的行为
### 观察者的实现
`
public interface Observer {
void update(Observable o, Object arg);
}
`
java提供了一个Observer接口,并有一个 update 方法。观察者只需要实现Observer接口,并实现update方法,表示收到被观察者变更通知之后的行为
`
public class CurrentCondition implements Observer {
private float temperature;
private float pressure;
private float humitidy;
public void display(){
System.out.println(temperature+","+pressure+","+humitidy);
}
@Override
public void update(Observable o, Object arg) {
this.temperature = ((WetherData)o).getTemperature();
this.pressure = ((WetherData)o).getPressure();
this.humitidy = ((WetherData)o).getHumidity();
display();
}
}
`
### 被观察者
同样java提供了Observable类,被观察者需要继承该类
`
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);
}
/*
当本观察者发生变化,需要先讲change设置为true,就会通知所有的注册在 obs 变量里的观察者,
会调用观察者实现的update方法
再用clearChange方法将change设为false,表示不再变化
*/
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);
}
/**
* Clears the observer list so that this object no longer has any observers.
*/
public synchronized void deleteObservers() {
obs.removeAllElements();
}
/**
* Marks this <tt>Observable</tt> object as having been changed; the
* <tt>hasChanged</tt> method will now return <tt>true</tt>.
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* Indicates that this object has no longer changed, or that it has
* already notified all of its observers of its most recent change,
* so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
* This method is called automatically by the
* <code>notifyObservers</code> methods.
*
* @see java.util.Observable#notifyObservers()
* @see java.util.Observable#notifyObservers(java.lang.Object)
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* Tests if this object has changed.
*
* @return <code>true</code> if and only if the <code>setChanged</code>
* method has been called more recently than the
* <code>clearChanged</code> method on this object;
* <code>false</code> otherwise.
* @see java.util.Observable#clearChanged()
* @see java.util.Observable#setChanged()
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* Returns the number of observers of this <tt>Observable</tt> object.
*
* @return the number of observers of this object.
*/
public synchronized int countObservers() {
return obs.size();
}
}
`
实现如下:
`
public class WetherData extends Observable {
private float temperature;
private float pressure;
private float humidity;
public float getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
public void setData(float temperature,float pressure,float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
//需要先调用setChanged()方法,
setChanged();
notifyObservers(); //这个方法里面会将change的状态清除
}
}
`
`
public class Wether {
public static void main(String[] args) {
WetherData wetherData = new WetherData();
CurrentCondition currentCondition = new CurrentCondition();
wetherData.addObserver(currentCondition);
wetherData.setData(112,22,221);
}
}
`