观察者模式是这样定义的:在对象之间存在一对多的依赖关系,当主对象的状态发生改变的时候,依赖它的全部从对象都能接收到改变的信息并作出相应的处理。好比老师和学生,微信公众号和订阅的用户,消息队列的生产者和消费者。观察者模式的实质就是发布订阅模式,发布者发布消息,订阅者获取消息,订阅了就能收到消息,没订阅就收不到消息。bash
观察者模式有四个角色:
一、抽象被观察者:也就是一个抽象的主题,它将全部观察者放到一个集合(队列)中,这个主题定义了添加观察者、一处观察者,以及通知观察者等方法。
二、抽象观察者:为具体的观察者定义了一个接口
三、具体被观察者:对应一个具体的主题,在自身主题的内部发生变化时,通知集合中的全部观察者
四、具体观察者:依赖具体的被观察者,对应它的主题,实现接收通知的接口。微信
你们都熟悉这么一个场景,咱们订阅了不少了微信公众号,这些微信公众号后台都有管理员在运营,当他们在后台发布了一篇推文,咱们这些订阅了的用户均可以收到这篇推文,微信公众号就是被观察者,订阅的用户就是观察者。ide
/**
* 抽象被观察者接口,定义添加,移除和通知观察者的接口
*/
public interface Observable {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
复制代码
/**
* 抽象观察者接口,定义接收通知方法
*/
public interface Observer {
public void updateMessage(String message);
}
复制代码
/**
* 被观察者,微信公众号/服务号/订阅号
* 实现了Observable,实现添加订阅者,删除订阅者,通知订阅者的基本功能
*/
public class WechatServer implements Observable{
private List<Observer> observers;
private String message;
public WechatServer() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
if (observers == null) {
observers = new ArrayList<>();
}
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if (observers == null || observers.isEmpty()) {
return;
}
observers.remove(observer);
}
@Override
public void notifyObserver() {
if (observers == null) {
return;
}
for (Observer observer : observers) {
observer.updateMessage(message);
}
}
public void publicMessage(String message) {
if (StringUtils.isBlank(message)) {
throw new IllegalArgumentException("不能发布空消息");
}
this.message = message;
System.out.println("微信公众号管理员发布信息:"+message);
//通知全部订阅者
notifyObserver();
}
}
复制代码
public class WechatUser implements Observer{
private String name;
private String message;
public WechatUser(String name) {
this.name = name;
}
@Override
public void updateMessage(String message) {
this.message = message;
System.out.println(name+"收到推送消息:"+message);
}
}
复制代码
public static void main(String [] args) {
//定义微信公众号
WechatServer server = new WechatServer();
//定义三个订阅的用户
WechatUser user1 = new WechatUser("乔峰");
WechatUser user2 = new WechatUser("令狐冲");
WechatUser user3 = new WechatUser("杨过");
//三人订阅了公众号
server.registerObserver(user1);
server.registerObserver(user2);
server.registerObserver(user3);
//微信公众号发布消息
server.publicMessage("JAVA是最流行的语言!!");
//乔峰取消了订阅
server.removeObserver(user1);
//微信公众号再次发布消息(取消订阅的用户郑光宇就收不到消息了)
server.publicMessage("JAVA是最好用的语言!!");
}
复制代码
运行结果:测试