观察者模式 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
这就好比一个办在线教育的老师 (OnlineTeacher) 和线下的若干学生 (localStudent1, localStudent2, localStudent3 …) 之间的关系。
当这个老师在线上发布了一条消息之后,他所有的学生都会收到通知,并可以根据这条消息的内容来实现对应的更新。
为了实现 松耦合 设计,OnlineTeacher 对象只需要实现 Subject
接口,并实现其中规定的三个方法即可:
- registerObserver(); // 注册观察者
- removeObserver(); // 取消注册观察者
- notifyObserver(); // 通知观察者
public interface Subject {
//Subject 接口中的三个方法, 用于注册、移除和通知 observers
void registerObserver(Observer observer);
void removeObserver(Observer observer);
// 以上两个方法都需要一个 observer 对象作为变量,以实现注册或被删除
void notifyObservers();}
同时,OnlineTeacher 对象还需要一个数据结构,来存储已经注册的学生对象。
public class OnlineTeacher implements Subject {
// 建立一个数据结构来存储注册过的 observer 对象
private ArrayList<Observer> observerArrayList;
// 用 message 来模拟老师讲课
private String message;
//OnlineTeacher 类的构造器,生成该对象时,会初始化一个 observerArrayList
public OnlineTeacher() {observerArrayList = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {observerArrayList.add(observer);
}
@Override
public void removeObserver(Observer observer) {int i = observerArrayList.indexOf(observer);
if (i > 0) {observerArrayList.remove(i);
}
}
// 实现 notifyObservers(),实质上就是遍历 observerArrayList,让其中的每一个 observer 对象调用他们的 update()方法
@Override
public void notifyObservers() {for (int i = 0; i < observerArrayList.size(); i++) {observerArrayList.get(i).updates(message);
}
}
//OnlineTeacher 有一个方法,setMessage()
public void setMessage(String newMessage) {
this.message = newMessage;
messageChanged(); //message 赋值之后,调用 messageChanged()方法
}
// 还有一个方法,messageChanged, 在此方法中调用 notifyObservers()
public void messageChanged() {notifyObservers();
}
}
而所有的学生对象只需要实现 Observer
接口即可成为“观察者”。
所有的观察者只需要保有一个 OnlineTeacher 对象的引用,便可以在各自的构造器中实现对自身的注册。
public interface Observer {void updates(String message);
}
localStudent1 类:
public class LocalStudent1 implements Observer {
private Subject onlineTeacher;
// 构造器需要 OnlineTeacher 对象(也就是 subject),用来注册自己
public LocalStudent1(Subject onlineTeacher) {
this.onlineTeacher = onlineTeacher;
onlineTeacher.registerObserver(this);
}
@Override
public void updates(String message) {
System.out.println("localStudent1 从 onlineTeacher 那儿得到的 message 是:" +
message +','+
"我领悟到的是: 女子和小人一样");
}
}
localStudent2 类:
public class LocalStudent2 implements Observer {
private Subject onlineTeacher;
public LocalStudent2(Subject onlineTeacher) {
this.onlineTeacher = onlineTeacher;
onlineTeacher.registerObserver(this);
}
@Override
public void updates(String message) {
System.out.println("localStudent2 从 onlineTeacher 那儿得到的 message 是:" +
message +','+
"我领悟到的是: 这话还有后半句——近之则不逊,远之则怨");
}
}
localStudent3 类:
public class LocalStudent3 implements Observer{
private Subject onlineTeacher;
public LocalStudent3(Subject onlineTeacher) {
this.onlineTeacher = onlineTeacher;
onlineTeacher.registerObserver(this);
}
@Override
public void updates(String message) {
System.out.println("localStudent3 从 onlineTeacher 那儿得到的 message 是:" +
message +','+
"我领悟到的是: 一个人对他亲近了,他对你不尊重,疏远了却又有怨言!");
}
}
public class ObserverPatternRunDemo {public static void main (String [] args){OnlineTeacher onlineTeacher = new OnlineTeacher();
LocalStudent1 localStudent1 = new LocalStudent1(onlineTeacher);
LocalStudent2 localStudent2 = new LocalStudent2(onlineTeacher);
LocalStudent3 localStudent3 = new LocalStudent3(onlineTeacher);
onlineTeacher.setMessage("子曰:唯女子与小人难养也");
}
}
运行时,以 localStudent1 对象为例。生成该对象时,会调用 onlineTeacher 对象的 registerObserver() 方法
,将其自身加入到 onlineTeacher 对象的observerArrayList
当中。
当 onlineTeacher 对象调用 setMessage("子曰:唯女子与小人难养也");
时,相当于 message
的值为 子曰:唯女子与小人难养也
。
//OnlineTeacher.java 中定义的 setMessage()和 messageChanged()方法
...
//OnlineTeacher 有一个方法,setMessage()
public void setMessage(String newMessage) {
this.message = newMessage;
messageChanged(); //message 赋值之后,调用 messageChanged()方法
}
// 还有一个方法,messageChanged, 在此方法中调用 notifyObservers()
public void messageChanged() {notifyObservers();
}
}
...
根据 onlineTeacher
类中定义的方法,应有:
先调用 messageChanged() 方法
,然后会调用notifyObservers() 方法
, 而notifyObservers()
方法会遍历所有的 Observer 对象,并调用他们的 update() 方法
:
// 实现 notifyObservers(),实质上就是遍历 observerArrayList,让其中的每一个 observer 对象调用他们的 update()方法
@Override
public void notifyObservers() {for (int i = 0; i < observerArrayList.size(); i++) {observerArrayList.get(i).updates(message);
}
}
3 个 localStudent 对象的 update() 方法
:
localStudent1.update();
@Override
public void updates(String message) {
System.out.println("localStudent1 从 onlineTeacher 那儿得到的 message 是:" +
message +','+
"我领悟到的是: 女子和小人一样");
}
}
localStudent2.update();
@Override
public void updates(String message) {
System.out.println("localStudent2 从 onlineTeacher 那儿得到的 message 是:" +
message +','+
"我领悟到的是: 这话还有后半句——近之则不逊,远之则怨");
}
**localStudent3.update();**
@Override
public void updates(String message) {
System.out.println("localStudent3 从 onlineTeacher 那儿得到的 message 是:" +
message +','+
"我领悟到的是: 一个人对他亲近了,他对你不尊重,疏远了却又有怨言!");
}
localStudent1 从 onlineTeacher 那儿得到的 message 是:子曰:唯女子与小人难养也, 我领悟到的是: 女子和小人一样
localStudent2 从 onlineTeacher 那儿得到的 message 是:子曰:唯女子与小人难养也, 我领悟到的是: 这话还有后半句——近之则不逊,远之则怨
localStudent3 从 onlineTeacher 那儿得到的 message 是:子曰:唯女子与小人难养也, 我领悟到的是: 一个人对他亲近了,他对你不尊重,疏远了却又有怨言!