观察者模式

1.定义

观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式),在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

2.具体实现

2.1类图

image-20210301184421521

2.2 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package 设计模式;

public class ObserverPattern {
public static void main(String[] args) {
Ring ring = new OverClassRing();
Student student1 = new MiddleSchoolStudent();
Student student2 = new collegeStudent();
ring.add(student1);
ring.add(student2);
ring.notice();
}
}
//抽象目标:铃声
abstract class Ring{
protected List<Student> students = new ArrayList<Student>();

//添加观察者
public void add(Student student){
students.add(student);
}
//删除观察者
public void delete(Student student){
students.remove(student);
}

public abstract void notice();
}
//具体目标:下课铃声
class OverClassRing extends Ring{

@Override
public void notice() {
for (Student student : students) {
student.response();
}
}
}



//抽象观察者:学生
interface Student{
void response();
}
//具体观察者1:大学生
class collegeStudent implements Student{

@Override
public void response() {
System.out.println("高数课下课了,我们会寝室学习吧(玩耍)");
}
}
//具体观察者2:中学生
class MiddleSchoolStudent implements Student{

@Override
public void response() {
System.out.println("语文课下课了,我们开始预习下节数学课吧");
}
}

3.优点

观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。

4.缺点

在应用观察者模式时需要考虑一下开发小路问题,程序中包括一个被观察者和多个被观察者,开发和调试比较复杂,而且Java中的消息的通知默认是顺序执行的,一个观察者的卡顿会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。

5.使用场景

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

  • 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要被改变。

  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,不希望这些对象是紧密耦合的。