定义
观察者模式也叫发布订阅模式,该模式定义对象间一种一对多的依赖关系,使得没当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
观察者一般可以看做是第三者,比如在学校上自习的时候,大家肯定都有过交头接耳、各种玩耍的经历,这时总会有一个“放风”的小伙伴,当老师即将出现时及时“通知”大家老师来了。再比如,拍卖会的时候,大家相互叫价,拍卖师会观察最高标价,然后通知给其它竞价者竞价,这就是一个观察者模式。
结构和实现
结构
- Subject被观察者:
定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。他一般是抽象类或者实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者 - Oberver观察者
观察者接收到消息后,以及进行update操作,对接收到的信息进行处理 - ConcreteSubject具体被观察者
定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知 - ConcreteObserver具体的观察者
每个观察者在接收到消息后的处理反应是不同的,各个观察者有自己的处理逻辑
实现
被观察者
public class Subject {
//观察者数组
private Vector<Observer> oVector = new Vector<>();
//增加一个观察者
public void addObserver(Observer observer) {
this.oVector.add(observer);
}
//删除一个观察者
public void deleteObserver(Observer observer) {
this.oVector.remove(observer);
}
//通知所有观察者
public void notifyObserver() {
for(Observer observer : this.oVector) {
observer.update();
}
}
}
具体被观察者
public class ConcreteSubject extends Subject {
//具体业务
public void doSomething() {
//...
super.notifyObserver();
}
}
观察者
public interface Observer {
//更新
public void update();
}
具体观察者
public class ConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("收到消息,进行处理");
}
}
Client
public class Client {
public static void main(String[] args) {
//创建一个主题
ConcreteSubject subject = new ConcreteSubject();
//定义一个观察者
Observer observer = new ConcreteObserver();
//观察
subject.addObserver(observer);
//开始活动
subject.doSomething();
}
}
总结
优点
- 观察者与被观察者之间是抽象耦合的
- 建立一套触发机制
缺点
如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。效率很低。所以需要异步
适用场景
- 关联行为场景
- 事件多级触发场景
- 跨系统的消息变换场景,如消息队列的处理机制