定义:
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
定义了对象之间的一对多依赖(一个主题,多个观察者),这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
也叫做发布订阅模式Publish/Subscribe.
类图:
abstract class Subject {
private Vector<Observer> obs = new Vector<Observer>();
public void addObserver(Observer obs){
this.obs.add(obs);
}
public void delObserver(Observer obs){
this.obs.remove(obs);
}
protected void notifyObserver(){
for(Observer o: obs){
o.update();
}
}
……
}
四个角色:
1)Subject被观察者
一般是抽象类或实现类,用于管理观察者并通知观察者。必须能动态地添加、取消观察者。
2)Observer观察者
一般是接口,定义update方法。当收到消息后,执行update。
3)ConcreteSubject具体的被观察者
定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
4)ConcreteObserver具体的观察者
实现update(),进行收到消息后的处理逻辑。
Java API内置的观察者
java.util.Observable --Subject被观察者
java.util.Observer --Observer观察者
——可以选择是用“推”还是“拉”的方式,来传送数据
Observable中无需用List来保存观察者!
notifyObservers()有两个重载版本:
- 无参数的表示“拉”。由Observer主动向其索取数据。
- 有参数的表示“推”。由Observable主动向观察发送数据。
public class MySubject extends Observable{
private Object data; //一般是个JavaBean
public void changeData(){
setChanged(); //若不调用,则观察者不会被通知
notifyObservers(); //拉
notifyObservers(data); //推
}
}
public class Observer1 implements Observer{
Observable observable;
public Observer1(Observable o){
observable = o;
observable.addObserver(this);//注册
}
public void update(Observable o, Object arg){
if(o instanceof MySubject){
Object data = ((MySubject) o).getData(); //主动索取数据
...
}
}
}
优点:
观察者和被观察者之间是抽象耦合,--松耦合。
建立一套触发机制,形成一个触发链。
缺点:
广度:观察者比较多时,多级触发的效率不高。
深度:在观察者模式中,最多出现一个对象即是观察者又是被观察者。
使用场景:
- 关联行为场景
- 事件多级触发场景
- 跨系统的消息交换场景
与其他模式的关系:
注意区分责任链模式。观察者广播链在传播过程中消息是随时更改的;而责任链模式在消息传递过程中基本保持消息不可变。