基本简介
观察者模式也被称为发布-订阅模式,属于行为模式的一种。
定义:在对象之间定义一种一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会接收到通知,并自动更新
类图结构
基本思路
- 构造一个主题接口,再构造一个具体的主题类来实现主题接口,用来管理观察者,并向观察者来发送通知
- 构造一个观察者接口,再根据业务来定义多个观察者类实现观察者接口,通过调用update()方法来接收从主题发出来的内容
实现代码
下面用观察者模式,用代码来实现以下微信公众号来向关注这个公众号的用户发送消息。
抽象观察者接口(Observer)
public interface IObserver {
//主题发生改变时,更新通知
void update(String msg);
}
抽象主题接口(Subject)
public interface ISubject {
//注册观察者
void registerObserver(IObserver observer);
//移除观察者
void removeObserver(IObserver observer);
//通知观察者
void notifyObservers();
}
具体的观察者
public class Person implements IObserver {
private String name;
private String message;
public Person(String name) {
this.name = name;
}
@Override
public void update(String msg) {
this.message = msg;
this.read();
}
public void read() {
System.out.println(name + "接收到的消息为:" + message);
}
}
具体的主题
public class WxSubject implements ISubject {
//保存关注了公众号的观察者人员
private List<IObserver> observerList;
private String message;
public WxSubject(){
this.observerList = new ArrayList<>();
}
@Override
public void registerObserver(IObserver observer) {
observerList.add(observer);
}
@Override
public void removeObserver(IObserver observer) {
if(!observerList.isEmpty()){
observerList.remove(observer);
}
}
//向各个观察者发送通知
@Override
public void notifyObservers() {
for(IObserver observer : observerList){
observer.update(message);
}
}
//设置消息内容
public void setInfomation(String msg){
this.message = msg;
System.out.println("微信公众号更新消息:"+msg);
notifyObservers();
}
}
测试类
public class CMain {
public static void main(String[] args) {
//定义一个主题(微信公众号)
WxSubject wxSubject = new WxSubject();
//定义三个观察者(普通用户)
Person personA = new Person("张三");
Person personB = new Person("李四");
Person personC = new Person("王五");
//将观察者注册到主题上(用户关注公众号)
wxSubject.registerObserver(personA);
wxSubject.registerObserver(personB);
wxSubject.registerObserver(personC);
//公众号发布消息
wxSubject.setInfomation("发送通知,明天有雨");
System.out.println("===================================");
//主题移除观察者(用户B取消关注公众号)
wxSubject.removeObserver(personB);
wxSubject.setInfomation("再次通知,明天雷阵雨黄色警告");
}
}
执行结果如下:
微信公众号更新消息:发送通知,明天有雨
张三接收到的消息为:发送通知,明天有雨
李四接收到的消息为:发送通知,明天有雨
王五接收到的消息为:发送通知,明天有雨
===================================
微信公众号更新消息:再次通知,明天雷阵雨黄色警告
张三接收到的消息为:再次通知,明天雷阵雨黄色警告
王五接收到的消息为:再次通知,明天雷阵雨黄色警告
主题发布消息,各个观察者均收到消息。从主题中移除观察者后,再次发送通知,只有现有的注册到主题上的观察者才能接收到消息。
总结
- 观察者模式是一种松耦合的模式,改变主题或观察者其中一方,并不会影响另一方
- JDK中内置了观察者模式,但是其观察者不是接口而是一个类,这限制了它的使用和复用
- 在JDK中,
JavaBeans
和Swing
中都实现了观察者模式