观察者模式
- 定义: 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
- 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- 关键:在被观察者类里有一个 集合 存放观察者们。
- 优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
- 缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
- 举例: 就好比我今天要举的例子,班长是被观察者对象,有很多的学生也就是观察者,学生观察班长,当班长看到老师来了,就会喊老师来了, 同学们怕被抓到就会去学习, 这也就是观察者模式的优点观察者和被观察者是抽象耦合的和一键触发机制, 但是又有缺点, 如果人数太多, 比如隔壁班的也在观察我们班的班长, 那人数太多就会通知起来太慢, 而且如果隔壁班的班长不是观察我们班的班长, 就会造成循环通知, 就是我们班班长通知一遍, 然后隔壁班班长有通知一遍, 就会造成循环调用, 最主要的是学生知识知道老师来了, 并不知道是哪个老师来了, 这对要准备书本的学生不是很友好
- 下面我们用代码实现这个例子
实现
public interface Observer {
void update();
}
public class Student implements Observer {
private String name;
private boolean studying;
public Student(String name, boolean studying) {
this.name = name;
this.studying = studying;
}
@Override
public void update() {
if (studying) {
System.out.println(name + "依旧学习");
} else {
System.out.println(name + "吓了一跳然后开始学习");
this.studying = true;
}
}
}
public interface Observable {
void addObserver(Observer observer);
void deleteObserver(Observer observer);
void notifyObserver();
}
public class Monitor implements Observable {
private Vector<Observer> students;
public Monitor() {
this.students = new Vector<>();
}
@Override
public void addObserver(Observer observer) {
this.students.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
this.students.remove(observer);
}
@Override
public void notifyObserver() {
System.out.println("老师来了!!!");
for (Observer observer : this.students
) {
observer.update();
}
}
}
public class Client {
public static void main(String[] args) {
Monitor monitor = new Monitor();
Student a = new Student("a", true);
Student b = new Student("b", false);
Student c = new Student("c", true);
Student d = new Student("d", false);
Student e = new Student("e", false);
monitor.addObserver(a);
monitor.addObserver(b);
monitor.addObserver(c);
monitor.addObserver(d);
monitor.addObserver(e);
monitor.notifyObserver();
}
}
- 结果