1.概念:
在对象之间定义一对多的依赖关系,这样一来,当一个对象改变状态,依赖它的对象会接到通知,并自动更新。
2.原则:
- 封装变化:找出程序中会变化的地方,然后将其和固定不变的方面分离。在观察者模式中会改变的是主题的状态,以及观察者的数目和类型。用这个模式你可以改变依赖主题状态的对象,却不用改变主题,这就是提前规划。
- 针对接口编程,不针对实现编程:主题和观察者都使用了接口。观察者利用主题的接口进行注册,而主题利用观察者的接口通知观察者;
- 多组合,少继承:观察者模式将许多观察者“组合”进主题中。对象中的这种关系不是继承产生的,而是在运行时利用组合的方式产生的。
- 为交互对象之间的松耦合设计而努力
3.JDK的支持
java.util.Observer 接口
java.util.Observerable 类
package java.util;
/**
* 观察者
*/
public interface Observer {
void update(Observable o, Object arg);
}
package java.util;
/**
* 主题
*/
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);
}
}
/**
* Deletes an observer from the set of observers of this object.
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
public void notifyObservers() {
notifyObservers(null);
}
public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
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();
}
}