定义
观察者模式也叫发布订阅模式,定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
通用类图
具体实现
观察者模式中有观察者和被观察者角色,他们之间的关系往往是一对多的关系,也就是一个被观察者对应多个观察者,当被观察者状态变化时,要通知其每个观察者对象。
被观察者 Subject ,一般是抽象类或者是实现类,主要的职责是管理观察者并通知观察者。
package com.yrs.observer;
import java.util.Vector;
/**
* @Author: yangrusheng
* @Description: 被观察者抽象类
* @Date: Created in 12:46 2020/4/12
* @Modified By:
*/
public abstract class Subject {
//定义存储观察者对象容器
private Vector<Observer> observers = new Vector<>();
/**
* 添加观察者
* @param observer
*/
public void attach(Observer observer) {
observers.add(observer);
}
/**
* 移除观察者
* @param observer
*/
public void detach(Observer observer) {
observers.remove(observer);
}
/**
* 通知所有观察者
*/
public void notifyObserver() {
for (Observer observer: observers) {
observer.update();
}
}
}
具体的观察者 ConcreteSubjectA,它主要实现自己的业务逻辑,同时定义哪些事件会通知观察者。
package com.yrs.observer;
/**
* @Author: yangrusheng
* @Description: 具体被观察者类
* @Date: Created in 12:56 2020/4/12
* @Modified By:
*/
public class ConcreteSubjectA extends Subject {
/**
* 具体业务
*/
public void doSomething() {
System.out.println("concreteSubjectA begin do something.");
super.notifyObserver();
}
}
观察者 Observer,观察者在接收到消息后,将执行 update 方法,对信息进行业务处理。
package com.yrs.observer;
/**
* @Author: yangrusheng
* @Description:
* @Date: Created in 12:47 2020/4/12
* @Modified By:
*/
public interface Observer {
/**
* 更新方法
*/
void update();
}
具体观察者 ConcreteObserverA
package com.yrs.observer;
/**
* @Author: yangrusheng
* @Description: 具体观察者
* @Date: Created in 13:03 2020/4/12
* @Modified By:
*/
public class ConcreteObserverA implements Observer {
@Override
public void update() {
System.out.println("concreteObserverA receive notify, begin update");
}
}
场景类 Client
package com.yrs.observer;
/**
* @Author: yangrusheng
* @Description: 场景类
* @Date: Created in 13:07 2020/4/12
* @Modified By:
*/
public class Client {
public static void main(String[] args) {
//定义被观察者
ConcreteSubjectA subject = new ConcreteSubjectA();
//定义观察者
Observer observerA = new ConcreteObserverA();
Observer observerB = new ConcreteObserverB();
//添加观察者
subject.attach(observerA);
subject.attach(observerB);
//被观察者活动
subject.doSomething();
}
}
优缺点
观察者模式的优点
- 观察者和被观察者之间是抽象耦合。使之方便扩展。
- 建立一套触发机制。
观察者模式的缺点
在观察者模式中,一般一个被观察者对应多个观察者,开发和调试会变得复杂。另一个需要注意的是,在通知观察者时往往顺序执行,如果其中一个观察者执行阻塞,就会影响通知剩余的观察者。这种情况下,一般采用异步的方式处理,防止影响整体性能。
使用场景
- 关联行为场景。
- 事件多级触发场景。
- 跨系统的消息交换场景,如消息队列的处理机制。
注意事项
- 广播链问题。如果观察者有双重身份,既是观察者,也是被观察者,他们之间一旦形成链,那么逻辑将变得复杂,难以维护。建议一个观察者模式中最多出现一个对象既是观察者也是被观察者,这样比较好控制。
- 异步处理问题。
Java 中的观察者模式:java.util.Observable、java.util.Observer
参考
- 《设计模式之禅-第2版》