定义
定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者(观察者)都会收到通知并更新。
类型
行为型
适用场景
①、关联行为场景,建立一套触发机制。
优缺点
优点:
①、观察者和被观察者之间建立了一个抽象的耦合。
②、观察者模式支持广播通信。
缺点:
①、观察者之间有过多的细节依赖、提高时间消耗及程序复杂度。
②、使用要得当,要避免循环调用。
代码实现
案例:老师在每节课的课后都会收到同学提出的问题。这里课程就是一个被观察者,而老师作为一个观察者。
首先创建一门课程
public class Course extends Observable {
private String courseName;
public Course(String courseName) {
this.courseName = courseName;
}
public String getCourseName() {
return courseName;
}
public void produceQuestion(Course course, Question question) {
System.out.println(question.getUserName() + "在" + course.getCourseName() + "这门课程提出了问题");
setChanged();
notifyObservers(question);
}
}
这里继承Observable这个类,表明这是一个被观察者。
setChanged()方法:标记此 Observable对象为已改变的对象。
notifyObservers(question):通知所有观察者。
接下来创建问题类
public class Question {
private String userName;
private String questionContent;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getQuestionContent() {
return questionContent;
}
public void setQuestionContent(String questionContent) {
this.questionContent = questionContent;
}
}
这个类提供了提出问题人的名字和问题内容。
最后创建观察者
public class Teacher implements Observer {
private String teacherName;
public Teacher(String teacherName) {
this.teacherName = teacherName;
}
@Override
public void update(Observable o, Object arg) {
Course course = (Course) o;
Question question = (Question) arg;
System.out.println(teacherName + "老师的" + course.getCourseName() + "课程收到了" + question.getUserName() + "同学提出的:" + question.getQuestionContent() + "这个问题");
}
}
Observer这是一个接口,实现这个类,表明Teacher是一个观察者,需要实现update()这个方法。当有被观察者发生变化时,自动调用update()这个方法,o是被观察者对象,arg是被观察者传过来的发生变化的数据对象。
编写测试类
public class MainTest {
public static void main(String[] args) {
Course course = new Course("Java设计模式");
Teacher teacher1 = new Teacher("qfcwx");
Teacher teacher2 = new Teacher("清风");
// 添加观察者
course.addObserver(teacher1);
course.addObserver(teacher2);
// 业务逻辑代码
Question question = new Question();
question.setUserName("小明");
question.setQuestionContent("观察者模式该怎么学习呢?");
course.produceQuestion(course, question);
}
}
这里设定了两个老师作为观察者来观察课程的变化。
输出结果:
C:\android\java\jdk1.8\bin\java.exe
小明在Java设计模式这门课程提出了问题
清风老师的Java设计模式课程收到了小明同学提出的:观察者模式该怎么学习呢?这个问题
qfcwx老师的Java设计模式课程收到了小明同学提出的:观察者模式该怎么学习呢?这个问题
相关源码
1. Jdk中的EventListener监听器(发布订阅模式)
2. 谷歌Guava中的EventBus