观察者模式:
观察者模式(Observer Pattern)定义了对象之间的一对多依赖,让多个观察者对象同 时监听一个主体对象,当主体对象发生变化时,它的所有依赖者(观察者)都会收到通 知并更新,属于行为型模式。
观察者模式有时也叫做发布订阅模式。观察者模式主要用 于在关联行为之间建立一套触发机制的场景。观察者模式在现实生活应用也非常广泛, 比如:微信朋友圈动态通知
-
结合案例,学生在教育系统提交问题,并且通知老师
-
创建发布问题的教育系统类
public class Edusystem extends Observable {
public final static String name = "教育系统";
public void publishQuestion(Question question){
System.out.println(question.getUserName()+"在"+name+"提交了一个问题");
setChanged();
notifyObservers(question);
}
}
- 创建问题
@Data
public class Question {
private String userName;
private String content;
}
- 创建老师监听
public class Teacher implements Observer {
private String name;
public Teacher(String name){
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
Edusystem edusystem = (Edusystem)o;
Question question = (Question)arg;
System.out.println(name+"你好,"+edusystem.name+"中收到问题");
System.out.println("提问者:"+question.getUserName());
System.out.println("问题内容:"+question.getContent());
}
}
- 测试
public class Test {
public static void main(String[] args){
Edusystem student = new Edusystem();
Question question = new Question();
question.setUserName("小明");
question.setContent("1+1等于几");
// 将指定的老师加入监听
student.addObserver(new Teacher("jack"));
student.addObserver(new Teacher("pony"));
student.publishQuestion(question);
}
}
- 测试结果:
-
JDK 源码中, 观察者模式也应用非常多。例如 java.awt.Event 就是观察者模式的一种。
-
观察者模式在Spring 中的应用, ContextLoaderListener 实现了 ServletContextListener 接口, ServletContextListener 接口又继承了 EventListener,在 JDK 中 EventListener 有非常 广泛的应用
-
另外基于 Guava API 可以轻松实现观察者模式。
- 加入依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
- 创建监听事件
public class GuavaEvent {
@Subscribe
public void subscribe(String str) {
//业务逻辑
System.out.println("执行 subscribe 方法,传入的参数是:" + str);
}
}
- 测试
public class Test {
public static void main(String[] args){
EventBus eventbus = new EventBus();
GuavaEvent guavaEvent = new GuavaEvent();
eventbus.register(guavaEvent);
eventbus.post("hahaa");
}
}
- 输出结果
-
观察者模式优缺点
优点:
1、观察者和被观察者之间建立了一个抽象的耦合
2、观察者模式支持广播通信
缺点:
1、观察者之间过多的细节依赖,提高时间消耗以及程序的复杂度
2、使用要得当,避免循环使用