Define a one-to-many dependency between objects so that when one object changes state,all its dependents are notified and updated automatically.
文章目录
定义
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新。
观察者通用类图:
- Subject被观察者:定义被观察者必须实现的职责,必须能够动态地增加、取消观察者。
- Observer观察者:观察者收到消息后,即进行update
- ConcreteSubject具体被观察者:定义被观察者自己的业务逻辑
- ConcreteObserver具体观察者:每个观察者收到消息后的处理反应不同,每个观察者有自己的处理逻辑。
被观察者:
public abstract class Subject {
// 定义一个观察者数组
private Vector<Observer> observerVector = new Vector<Observer>();
// 增加观察者
public void addObserver(Observer o){
this.observerVector.add(o);
}
// 删除观察者
public void delObserver(Observer o){
this.observerVector.remove(o);
}
// 通知所有观察者
public void notifyObservers(){
for (Observer observer : this.observerVector) {
observer.update();
}
}
}
具体被观察者:
public class ConcreteSubject extends Subject{
// 具体的业务
public void doSomething(){
/**
* do something
*/
System.out.println("执行吃饭业务");
super.notifyObservers();
}
}
观察者:
public interface Observer {
// 更新方法
public void update();
}
具体观察者:
public class ConcreteObserver implements Observer{
@Override
public void update() {
System.out.println("报~~~~大王,他活动了!");
}
}
场景类:
public class Client {
public static void main(String[] args) {
// 创建一个被观察者
ConcreteSubject subject = new ConcreteSubject();
// 定义一个观察者
Observer obs = new ConcreteObserver();
// 观察者观察被观察者
subject.addObserver(obs);
// 观察者活动了
subject.doSomething();
}
}
观察者模式的优缺点
优点:
- 观察者和被观察者直接是抽象耦合
- 建立一套触发机制,把单一职责串联成真实世界的复杂逻辑关系。比如,去打猎,打死一只母鹿,母鹿有三只幼崽,幼崽饿死,引来秃鹰抢夺,分配不均,秃鹰斗殴,获胜秃鹰因此扩大了地盘…这是一个触发机制,形成了一个触发链。
缺点:一个观察者卡壳,会影响整体的执行效率。
注意:
- 一个观察者模式中最多出现一个对象既是观察者又是被观察者,消息最多转发一次(传递两次),否则逻辑复杂,可维护性差。
- 观察者较多的时候,影响效率,可以采用异步处理。(异步要考虑线程安全和队列问题)
应用
适用场景:
- 并联行为场景
- 事件多级触发场景
- 跨系统的消息交换场景,如消息队列的处理机制
Java中的观察者模式
Java中已经造好*了,java.util.Observable这个类就是为了暴露的,被观察者继承Observable把自己的状态变更让别人知道,去触发。观察者可以实现java.util.Observer,从而实现观察者模式。
发布/订阅模型
消息的发布者发布一个消息,通知订阅者作出回应。