首页 > 应用开发 > IT综合 > 设计模式之观察者模式
观察者模式又称为发布-订阅(Publish/Subscribe)模式,是23种设计模式之一。DP中是这么定义观察者模式的:
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己。
举个生活中的例子,例如在某班级里,几个同学都在某个网站上订阅了一本连载的漫画。当漫画更新时,就会通知这几位同学,同学收到通知后就可以去下载漫画的最新篇章。这就是一个典型的观察者模式,在这里同学都是观察者,而漫画则是他们共同监听的一个主题,而漫画更新时也就是主题对象发生变化时,就会通知所有订阅该漫画的同学,所以漫画也就是通知者。同学们收到通知后就可以去下载漫画的新篇章了,这就是主题对象会通知观察者对象让他们进行更新。
我们使用简单的代码,来尝试实现一下这个场景:
漫画类,也就是主题:
package org.zero01.test;
import java.util.Vector;
// 漫画
public class Cartoon {
// 学生列表
private Vector<Student> studentList = new Vector();
// 漫画状态
private String action;
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
// 添加订阅该漫画的学生
public void attach(Student student) {
studentList.add(student);
}
// 漫画更新时通知学生
public void notifyOfStu() {
for (Student student : studentList) {
student.update();
}
}
}
学生类,也就是观察者:
package org.zero01.test;
public class Student {
private String name;
private Cartoon cartoon;
public Student(String name, Cartoon cartoon) {
this.name = name;
this.cartoon = cartoon;
}
// 得到通知时,就去下载新漫画
public void update() {
System.out.println(cartoon.getAction() + ", " + name + "请下载漫画的新篇章!");
}
}
客户端:
package org.zero01.test;
public class Client {
public static void main(String[] args) {
// 订阅的漫画
Cartoon cartoon=new Cartoon();
// 订阅该漫画的学生
Student student1=new Student("小明", cartoon);
Student student2=new Student("小红", cartoon);
// 添加订阅的学生
cartoon.attach(student1);
cartoon.attach(student2);
// 订阅的漫画更新了
cartoon.setAction("您订阅的XXX漫画更新啦");
// 通知订阅的学生
cartoon.notifyOfStu();
}
}
运行结果:
您订阅的XXX漫画更新啦, 小明请下载漫画的新篇章!
您订阅的XXX漫画更新啦, 小红请下载漫画的新篇章!
以上的代码实现了一个简单的观察者模式,当漫画这个主题对象的状态发生改变时,就会通知所有的订阅者。
我们编写的代码虽然可以实现以上所说到的场景,但是代码的耦合性很高,不能完全符合观察模式的设计理念。例如,我要增加一个订阅的是小说类型的学生,那么就得去修改 “漫画” 通知者的代码了。如果我还要增加一个 “小说” 通知者,让 小说” 通知者也能通知所有学生的话,也需要去修改学生类的代码,这就不符合开-闭原则了,而且对象之间互相依赖也违背了依赖倒转原则,以及以上的代码中没有编写取消订阅的方法也就是减少观察者的方法。
既然知道代码有哪些问题了,那么我们就来把这些代码重构一下:
代码结构图:
设计模式之观察者模式
1.首先抽象两个类:
package org.zero01.test;
// 通知者/主题接口
public interface Subject {
public void attach(Observer observer);
public void detach(Observer observer);
public void notifyOfStu();
public void setAction(String action);
public String getAction();
}
package org.zero01.test;
// 抽象观察者
public interface Observer {
public abstract void update();
}
2.然后才是具体的实现类:
漫画类:
package org.zero01.test;
import java.util.Vector;
// 漫画主题
public class Cartoon implements Subject{
// 学生列表
private Vector<Observer> observerList = new Vector();
// 主题动作
private String action;
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
// 添加订阅该漫画的学生
public void attach(Observer observer) {
observerList.add(observer);
}
// 漫画更新时通知学生
public void notifyOfStu() {
for (Observer observer : observerList) {
observer.update();
}
}
public void detach(Observer observer) {
observerList.remove(observer);
}
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69976870/viewspace-2711721/ ,如需转载,请注明出处,否则将追究法律责任。