定义
观察者模式是这样定义的:在对象之间存在一对多的依赖关系,当主对象的状态发生改变的时候,依赖它的所有从对象都能接收到改变的信息并做出相应的处理。比如老师和学生,微信公众号和订阅的用户,消息队列的生产者和消费者。观察者模式的实质就是订阅模式,者消息,订阅者获取消息,订阅了就能收到消息,没订阅就收不到消息。
UML
观察者模式有四个角色:
1、抽象被观察者:也就是一个抽象的主题,它将所有观察者放到一个集合(队列)中,这个主题定义了添加观察者、一处观察者,以及通知观察者等方法。
2、抽象观察者:为具体的观察者定义了一个接口
3、具体被观察者:对应一个具体的主题,在自身主题的内部发生变化时,通知集合中的所有观察者
4、具体观察者:依赖具体的被观察者,对应它的主题,实现接收通知的接口。
具体实现
大家都熟悉这么一个场景,我们订阅了很多了微信公众号,这些微信公众号后台都有管理员在运营,当他们在后台了一篇推文,我们这些订阅了的用户都可以收到这篇推文,微信公众号就是被观察者,订阅的用户就是观察者。
1.定义抽象被观察者接口
/**
* 抽象被观察者接口,定义添加,移除和通知观察者的接口
*/
public interface Observable {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
2.定义抽象观察者接口
/**
* 抽象观察者接口,定义接收通知方法
*/
public interface Observer {
public void updateMessage(String message);
}
3.定义具体被观察者类,表示一个特定主题(微信公众号),包含一个List集合,存储与之关联的观察者,对其进行管理(添加,移除和发送通知)
/**
* 被观察者,微信公众号/服务号/订阅号
* 实现了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();
}
}
4.定义具体观察者类,依赖微信公众号这一主题的就是订阅用户
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);
}
}
5.测试用例
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是最好用的语言!!");
}
运行结果: