0x01.简述
- 观察者模式(Observer Pattern)(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。(百度百科)
- 当对象间存在一对多关系时,可以使用观察者模式。
- 例如,当一个对象被修改时,则会自动通知它的依赖对象。
- 观察者模式属于行为型模式。
0x02.理解观察者模式
一个最为经典的例子:老师与同学的例子。
场景:
一个班的老师有10个学生,老师知道这10个学生的所有信息,老师讲课,学生都能听到,老师点名,对应的同学能起来回答问题。
把这一场景简单化:
-
其实就是满足了这样的关系:
- 老师拥有学生们的信息。
- 学生可以听到老师讲课和点名。
这个例子中的观察者模式:
- 老师与学生们是一对多的关系。
- 当老师讲课或者点名时,同学们能做出响应(当一个对象被修改时,则会自动通知它的依赖对象。)
- 在这个例子中,同学们就是观察者,老师就是被观察者。观察者观察被观察者的行为,并通过这些行为做出响应。
具体的关系可以参考下图:
- 将其抽象化,就是如下关系:
0x03.上述例子的实际代码实现
用代码将这一关系表示出来更容易理解!
-
总结一下上面的关系,明白我们代码需要做哪些事情:
- (1)一个老师有10名学生。
- (2)老师拥有学生的信息。
- (3)老师点名,学生答到。
-
接下来具体实现一下:
Person类:(父类)
- 包含老师和学生的公共属性。
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Student类:
- 有答到的方法。
public class Student extends Person {
public void daDao(){
System.out.println(super.getName()+":到!");
}
}
Teacher类:
- 包含学生的信息。
- 包含一个点到的方法。
public class Teacher extends Person{
//老师保留学生的信息
private List<Student> students = new ArrayList<Student>();
public void Dao() throws InterruptedException {
while(true){
int radom = (int)(Math.random()*10);
Student stu=students.get(radom);
System.out.println(stu.getName()+" 到了吗?");
stu.daDao();
Thread.sleep(3000);
}
}
public void addStu(Student stu){
this.students.add(stu);
}
}
Test:
public class Test {
public static void main(String[] args) throws InterruptedException {
Teacher teacher=new Teacher();
teacher.setName("王老师");
teacher.setAge(27);
for(int i=0;i<10;i++){
Student stu=new Student();
stu.setName("同学"+(i+1));
stu.setAge(18);
teacher.addStu(stu);
}
teacher.Dao();
}
}
效果展示:
0x04.回顾代码–再反思
从我们的代码中可以看出,实现这个小功能的核心代码是:
- 在Teacher类中存储了所有的Student的信息,这样,只要老师点到,就能调用学生的签到方法。
其实整个观察者模式中,最为重要的就是:当一个对象被修改时,则会自动通知它的依赖对象。
0x05.清楚优势
观察者模式主要用于一对多的关系,它在实际应用中的优势有:
- (1)降低了目标与观察者之间的耦合关系,将本来的耦合关系变成了抽象耦合关系。
- (2)目标与观察者之间建立了一套触发机制。
0x06.明白劣势
- (1)目标与观察者之间的依赖关系并没有完全解除,并且有可能出现循环引用。
- (2)当观察者直接或间接对象很多时,通知的发布会花费很多时间,影响程序执行的效率。
- (3)观察者模式仅仅只是知道观察目标发生了变化,无法让观察者知道所观察的目标对象是怎么发生变化的。
0x07.主要应用
Spring MVC的核心处理机制:
- 在Spring MVC的处理机制中,其实就使用到了观察者模式:
- 核心控制器就是被观察者,其余的对象就是观察者,当核心控制器发生改变(比如得到Handler),相应的对象就会收到通知,也做出相应的改变。
感谢@Mr.ml大佬的指导