观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
这就好比一个办在线教育的老师(OnlineTeacher)和线下的若干学生(localStudent1, localStudent2, localStudent3 ...)之间的关系。
当这个老师在线上发布了一条消息之后,他所有的学生都会收到通知,并可以根据这条消息的内容来实现对应的更新。
观察者模式类图
为了实现松耦合设计,OnlineTeacher对象只需要实现Subject
接口,并实现其中规定的三个方法即可:
- registerObserver(); //注册观察者
- removeObserver(); //取消注册观察者
- notifyObserver(); //通知观察者
Subject接口:
public interface Subject {
//Subject接口中的三个方法,用于注册、移除和通知observers
void registerObserver(Observer observer);
void removeObserver(Observer observer);
//以上两个方法都需要一个observer对象作为变量,以实现注册或被删除
void notifyObservers();
}
同时,OnlineTeacher对象还需要一个数据结构,来存储已经注册的学生对象。
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对象的引用,便可以在各自的构造器中实现对自身的注册。
Observer接口
public interface Observer {
void updates(String message);
}
用来模拟的localStudent对象们
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 +','+
"我领悟到的是:一个人对他亲近了,他对你不尊重,疏远了却又有怨言!");
}
}
运行ObserverPatternRunDemo.java
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 +','+
"我领悟到的是:一个人对他亲近了,他对你不尊重,疏远了却又有怨言!");
}
Demo运行的结果
localStudent1从onlineTeacher那儿得到的message是:子曰:唯女子与小人难养也,我领悟到的是:女子和小人一样
localStudent2从onlineTeacher那儿得到的message是:子曰:唯女子与小人难养也,我领悟到的是:这话还有后半句——近之则不逊,远之则怨
localStudent3从onlineTeacher那儿得到的message是:子曰:唯女子与小人难养也,我领悟到的是:一个人对他亲近了,他对你不尊重,疏远了却又有怨言!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。