观察者模式
用户在微信订阅了某公众号,当公众号发来消息,用户就会收到。
公众号就是被观察者,用户就是观察者。观察者只能被动的等候通知,而非主动询问。
被观察者又称主题。
观察者模式中有四个角色:
1、抽象主题角色
2、具体主题角色
3、抽象观察者角色
4、具体观察者角色
示例
事件:
public class Message {
private String content;
// getter & setter
}
抽象主题类:
public interface Subject {
Set<Observer> observers = new HashSet<>();
default void add(Observer observer){
observers.add(observer);
}
default void del(Observer observer){
observers.remove(observer);
}
void sendMessage(Message message);
}
observers 集合用于保存观察者,同时要提供添加观察者、删除观察者的方法,还有通知各观察者的方法。
具体主题类:
public class WechatSubject implements Subject{
@Override
public void sendMessage(Message message) {
observers.forEach(o ->{
o.getMessage(message);
});
}
}
添加通知观察者的方法,遍历通知所有观察者。
抽象观察者类:
public interface Observer {
void getMessage(Message message);
}
提供获取通知的方法。
具体观察者类:
public class ObserverA implements Observer{
@Override
public void getMessage(Message message) {
System.out.println("A 接收到推送 : "+message.getContent());
}
}
public class ObserverB implements Observer{
@Override
public void getMessage(Message message) {
System.out.println("观察者B已读过..." + message);
}
}
不同的观察者在被通知后有不同的处理。
测试:
Subject subject = new WechatSubject();
subject.add(new ObserverA());
subject.add(new ObserverB());
Message message = new Message();
message.setContent("这是一条推送");
subject.sendMessage(message);
总结
观察者模式是相对比较简单的设计模式。
此外JDK中提供了接口Observer和子类Observable,Observer表示观察者,Observable表示主题,可以用这两个实现观察者模式。但在Java9中已经不推荐这种写法了,而是推荐使用消息队列来实现。
Spring中的ApplicationListener就是观察者模式的实现,通过实现ApplicationContext接口我们可以监听:
- ContextRefreshedEvent容器刷新时间
- ContextStartedEvent容器开始事件
- ContextStoppedEvent容器停止事件
- ContextClosedEvent容器关闭事件
等。。。