一、模式介绍
观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
二、模式结构
三、模式代码
1、抽象观察者
package com.example.demo.observer;
//抽象观察者
public abstract class Observer {
public abstract void update(String msg);
}
2、 主题(被观察者)
package com.example.demo.observer;
import java.util.ArrayList;
import java.util.List;
//主题
public class Subject {
private List<Observer> observers = new ArrayList<>(); //状态改变
public void setMsg(String msg) {
notifyAll(msg);
}
//订阅(注册)
public void addAttach(Observer observer) {
observers.add(observer);
}
//通知所有订阅(注册)的观察者
private void notifyAll(String msg) {
for (Observer observer : observers) {
observer.update(msg);
}
}
}
3、观察者A
package com.example.demo.observer;
//A观察者
public class A_Student extends Observer {
public void update(String msg) {
System.out.println("A同学:"+msg+" "+"快看书!");
}
}
4、观察者B
package com.example.demo.observer;
//B观察者
public class B_Student extends Observer {
public void update(String msg) {
System.out.println("B同学:"+msg+" "+"手机收起来!");
}
}
5、观察者C
package com.example.demo.observer;
//C观察者
public class C_Student extends Observer {
public void update(String msg) {
System.out.println("C同学:"+msg+" "+"哎呀,书拿反了!");
}
}
6、模拟主题改变观察者状态
package com.example.demo.observer;
public class Main {
public static void main(String[] args) {
Subject subject = new Subject();
subject.addAttach(new A_Student());
subject.addAttach(new B_Student());
subject.addAttach(new C_Student());
subject.setMsg("老师来了!");
}
}
7、结果
四、使用情景
1、对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
2、对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
3、事件多级触发场景。
4、跨系统的消息交换场景,如消息队列、事件总线的处理机制。
五、优缺点
优点:
解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。
缺点:
在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。
六、demo地址
https://github.com/tongyuxin1/designModel/tree/master/src/main/java/com/example/demo