观察者模式也叫发布订阅模式,定义对象间的一种一对多的关系,使得每当一个对象改变状态,则所有依赖于它的对象都会收到通知并自动更新。
四种角色:
- Subject 被观察者,能够动态的添加和取消观察者,管理观察者并通知观察者。
- Observer 观察者,观察者收到通知后,执行自己的操作,对消息进行处理。
- ConcreteSubject 具体的被观察者,定义被观察者具体的业务逻辑。
- ConcreteObserver 具体的观察者,各个观察者有自己的业务逻辑。
// 被观察者抽象类
public abstract class Subject {
// 定义观察者集合
private Vector<Observer> obsVector = new Vector<Observer>();
// 添加一个观察者
public void addObserver(Observer obs){
this.obsVector.add(obs);
}
// 删除一个观察者
public void deleteObserver(Observer obs){
this.obsVector.remove(obs);
}
// 通知所有观察者,可以执行各自的更新方法了
public void notifyObservers(){
for(Observer o : obsVector){
o.update();
}
}
}
// 具体的被观察者
public class ConcreteSubject extends Subject {
// 业务方法
public void doSomething(){
// 方法中触发通知观察者
super.notifyObservers();
}
}
// 观察者接口
public interface Observer {
// 更新方法
public void update();
}
// 具体的观察者
public class ConcreteObserver implements Observer {
@Override
public void update() {
// 具体的更新方法
}
}
// 测试类
public class Test {
public static void main(String[] args) {
// 定义三个观察者
Observer obs1 = new ConcreteObserver();
Observer obs2 = new ConcreteObserver();
Observer obs3 = new ConcreteObserver();
// 定义一个被观察者
ConcreteSubject sub = new ConcreteSubject();
// 三个观察者都观察被观察者
sub.addObserver(obs1);
sub.addObserver(obs2);
sub.addObserver(obs3);
// 观察者执行某业务方法,触发通知时间通知三个观察者
sub.doSomething();
}
}
观察者与被观察者之间是抽象耦合的,所以观察者和被观察者都可以方便的扩展。
当在需要关联的场景时,考虑使用观察者模式,另外,在跨系统的消息交换场景,消息队列等,也要考虑使用观察者模式。
另外,在Java中,JDK提供了 java.util.Observable 类和 java.util.Observer 接口,对示例代码进行修改:
// 具体的被观察者
public class ConcreteSubject extends Observable {
// 业务方法
public void doSomething(){
// 方法中触发通知观察者
super.notifyObservers();
}
}
// 具体的观察者
public class ConcreteObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
// 具体的更新方法
}
}