定义:定义了对象之间一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并更新
类型:行为型
适用场景
- 关联行为场景,建立一套触发机制
优点
- 观察者和被观察者之间建立一个抽象的耦合
- 观察者模式支持广播通信
缺点
- 观察者之间由过多的细节依赖,提高时间消耗及程序复杂度
- 使用要得当,要避免循环调用
实现
观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
- Subject:就是“被观察”的角色,它将所有观察者对象的引用保存在一个集合中。
- Observer:是抽象的“观察”角色,它定义了一个更新接口,使得在被观察者状态发生改变时通知自己。
- ConcreteObserver:具体的观察者。
代码
在被观察者中建一个list,把观察者加到list里边
当被观察者执行方法时,遍历这个list调用观察者的方法
这里使用jdk中的类
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.courseName+"提交了一个问题");
setChanged();
notifyObservers(question);
}
}
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());
}
}
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 Test {
public static void main(String[] args) {
Course course = new Course("设计模式");
Teacher teacher1 = new Teacher("Alpha");
Teacher teacher2 = new Teacher("Beta");
course.addObserver(teacher1);
course.addObserver(teacher2);
//业务逻辑代码
Question question = new Question();
question.setUserName("Geeker");
question.setQuestionContent("Java的主函数如何编写");
course.produceQuestion(course,question);
}
}