定义对象间的一种一对多的依赖关系,当一个主题对象的状态发生改变时, 所有监听它的观察者对象都得到通知并被自动更新。
2.类图:
3.原理:
主题对象并不知道引用了哪些具体观察者对象类型,而只知道抽象观察者类型,这样具体主题对象可以动态地维护一系列的观察者对象的引用,并在需要的时候调用每一个观察者共有的更新方法。这是“针对接口编程”的体现。
4.特征:
抽象主题(Subject)角色:保存所有的观察者对象的引用到一个聚集里(如Vector),并提供注册或移除观察者的操作。一般用一个抽象类或一个接口实现。也称被观察者或发布者。
抽象观察者(Observer)角色:为具体观察者定义一个更新接口,更新接口中包含了更新的方法,在得到主题的通知时更新自己。一般用一个抽象类或一个接口实现。也称监听者或订阅者。
具体主题(ConcreteSubject)角色:实现抽象主题,在内部状态发生变化时,给所有注册的观察者发出通知。
具体观察者(ConcreteObserver)角色:实现抽象观察者角色所定义的更新方法, 在得到主题的通知时更新自己的状态。如有需要,具体观察者可以保存一个指向具体主题对象的引用。
5.说明:
6.使用案例:
Java.util.Observer 和 java.util.Observable
AWT事件模型,SAX2浏览器。
7.代码:
//Subject.java 抽象主题(Subject)角色
public class Subject
{
//保存所有注册的观察者对像的引用。
private ArrayList observers = new ArrayList();
//注册观察者
public void attach(Observer observer)
{
observers.add(observer);
}
//删除已注册的观察者
public void detach(Observer observer)
{
observers.remove(observer);
}
//通知所有的观察者
public void notifyObservers()
{
Iterator it = observers.iterator();
while (it.hasNext())
{
((Observer) it.next()).update(this);
}
}
}
// ConcreteSubject.java 具体主题(ConcreteSubject)角色
public class ConcreteSubject extends Subject
{
private String state;
//状态发生改变时通知所有的观察者
public void change(String newState)
{
this.state = newState;
notifyObservers();
}
public String getState()
{
return state;
}
}
// Observer.java抽象观察者(Observer)角色
public interface Observer
{
void update(Subject subject);
}
// ConcreteObserver.java具体观察者(ConcreteObserver)角色
public class ConcreteObserver implements Observer
{
public void update(Subject subject)
{
//put your code here
}
}