简介
也称发布订阅模式(Publish/Subscribe),定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
UML图:
应用场景:
- 消息通知组件:邮件通知、广播通知、朋友圈、私信等
- 当一个对象的改变需要同时改变其他对象,且不知道具体有多少对象有待改变时
示例
- 观察者:Observer
java
public interface Observer {
/**
* 更新状态
*/
void updateState();
}
java
public class ConcreteObserver01 implements Observer {
private String observerName;
private Subject subject;
public ConcreteObserver01(String observerName, Subject subject) {
this.observerName = observerName;
this.subject = subject;
}
@Override
public void updateState() {
System.out.println(subject.getAction() + "," + observerName + "进入工作状态");
}
}
java
public class ConcreteObserver02 implements Observer {
private String observerName;
private Subject subject;
public ConcreteObserver02(String observerName, Subject subject) {
this.observerName = observerName;
this.subject = subject;
}
@Override
public void updateState() {
System.out.println(subject.getAction() + "," + observerName + "进入工作状态");
}
}
- 目标/主体:Subject
java
public class Subject {
private List<Observer> observerList = new ArrayList<>();
private String action;
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public void addObserver(Observer observer) {
observerList.add(observer);
}
public void delObserver(Observer observer) {
observerList.remove(observer);
}
public void notifyObserver() {
for (Observer observer : observerList) {
observer.updateState();
}
}
}
java
public class BossSubject extends Subject {
}
- 运行
java
public class Main {
public static void main(String[] args) {
Subject bossSubject = new BossSubject();
Observer concreteObserver01 = new ConcreteObserver01("01员工摸鱼", bossSubject);
Observer concreteObserver02 = new ConcreteObserver02("02员工摸鱼", bossSubject);
bossSubject.addObserver(concreteObserver01);
bossSubject.addObserver(concreteObserver02);
bossSubject.setAction("老板开始巡视");
bossSubject.notifyObserver();
}
}
总结
-
优点:
- 观察者与被观察者是抽象耦合的,降低了目标与观察者之间的耦合关系
- 目标与观察者之间建立了一套触发机制
-
缺点
- 观察者与被观察者之间如果存在循环依赖,可能会触发彼此之间的循环调用,导致系统崩溃
- 若一个被观察者对象存在大量观察者对象,如果这些观察者对象都需要通知,会耗费大量时间