认识观察者模式
报纸和杂志的订阅
1.报社的业务就是出版报纸
2.向某家报社订阅报纸,只要他们有新报纸出版,只要你是他们的订户,你就会一直收到新报纸
3.当你不想再看报纸的时候,只要取消订阅,他们就不会再送报纸来
4.只要报社还在运营,就会一直有人(或单位)向他们订阅报纸或取消订阅报纸
出版者+订阅者=观察者模式
其实观察者模式的原理和报纸的订阅原理是一样的,只是名称不一样,出版者改称为”主题”(Subject),订阅者改称为”观察者”(Observer)
定义观察者模式
观察者模式定义了对象之间的一种一对多的依赖关系,这样一来,当一个对象改变状态时,他的所有依赖者都会受到通知并自动更新
不理解?让我们继续看看下面这示例图!
主题和观察者定义了一对多的关系,观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知,根据通知的风格,观察者可能因此新值而更新
在我们的实际应用中,实现观察者模式的方式不知一种,但是以包含Subject和Observer接口的类设计的做法最为常见,来看看下面这张图
这里我举一个学校点名的例子来实际应用下
首先创建我们所说的观察者和被观察者
创建抽象主题(被观察者)接口
public interface Observable {
//注册观察者
void registerObserver(Observer observer);
//移除观察者
void removeObserver(Observer observer);
/**
* 主题状态改变-->通知所有注册的观察者
* @param message 通知的消息
*/
void notifyObservers(String message);
}
创建观察者接口
public interface Observer {
//更新自己
void update(String message);
//这里用于区分每个观察者,根据实际需求
void setName(String name);
}
创建抽象主题接口实现类
public class Teacher implements Observable {
//用一个集合来存储所有的观察者
private List<Observer> mObserverList;
public Teacher() {
mObserverList = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
//向集合中添加观察者
mObserverList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
//从集合中移除观察者
mObserverList.remove(observer);
}
@Override
public void notifyObservers(String message) {
//遍历集合通知所有的观察者,自身数据变化了
for (Observer observer : mObserverList) {
observer.update(message);
}
}
}
创建具体观察者
public class Student implements Observer {
private String name;
@Override
public void update(String message) {
System.out.println("主题状态消息:" + message + "," + name + "到");
}
@Override
public void setName(String name) {
this.name = name;
}
}
运行示例
public class LessonStart {
public void main(String[] args) {
LessonStart lessonStart = new LessonStart();
Student s1 = new Student();
s1.setName("张三");
Student s2 = new Student();
s2.setName("李四");
Teacher teacher = new Teacher();
//注册两个观察者
teacher.registerObserver(s1);
teacher.registerObserver(s2);
//这里假设主题状态变-->通知观察者更新
teacher.notifyObservers("点名啦");
}
}
1、老师是被观察者,他需要实现接口的方法
注册/移除订阅:往集合中存放/移除观察者
发布:循环遍历观察者,调用观察者方法
2、学生是观察者,那么我们只需要给他个名字,实现观察者的方法即可
最后,我们就把观察者和被观察者关联起来,LessonStart (上课啦)
打印结果
主题状态消息:点名啦,张三到
主题状态消息:点名啦,李四到