前言
观察者,即时observer,总结来说就是一个当一个被观察的对象的状态发生变化时,会通知相应的观察者对象。
观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者
1.抽象主题(Subject):通常为接口或抽象类,定义一系列操作,如订阅,取消订阅,通知等方法
2.具体主题(Concrete Subject):具体主题,继承或实现抽象主题,实现相应的逻辑,如维护与观察者的关系,将自身的状态变化告知观察者。
3.抽象观察者(Observer):定义观察者行为
4.具体观察者(Concrete Observer):实现观察者行为,实现收到被观察者的通知后将要处理的逻辑
举个例子,Lz比较喜欢看杂志,所以订阅了“意林”杂志的公众号,此时我就是观察者,而“意林”杂志的公众号则是被观察者,当新一期的杂志出版时,即被观察者有状态变化,公众号就会给我推送通知。
所以说公众号是具体主题,而我是具体观察者,我们之间的关系是由公众号一方来维护的。
代码演示:
//抽象观察者
interface Observer{
public void update(String message);
}
//具体观察者
class MyWeixin implements Observer{ @Override
public void update(String message) {
System.out.println("我收到的通知: " + message);
}
}
//抽象主题
interface Subject{
//订阅
public void registerObserver(Observer observer);
//取消订阅
public void unregisterObserver(Observer observer);
//通知
public void notifyObserver(String message);
}
//具体主题,实现一系列逻辑操作,维护与观察者的关系
class YLi implements Subject{ //维护与观察者的关系
private List<Observer> relationList = new ArrayList<>(); @Override
public void registerObserver(Observer observer) {
relationList.add(observer);
} @Override
public void unregisterObserver(Observer observer) {
relationList.remove(observer);
} @Override
public void notifyObserver(String message) {
for (int i=0; i < relationList.size(); i++){
Observer observer = relationList.get(i);
observer.update(message);
}
}
}
测试代码:
public class ObserverPatternTest { public static void main(String[] args){
Observer observer = new MyWeixin();
Subject subject = new YLi();
subject.registerObserver(observer);
subject.notifyObserver("新的一期意林杂志出版了!");
subject.unregisterObserver(observer);
} }
控制台打印
总结:观察者模式在有的书里又称为发布/订阅模式,当需要对某个对象的状态进行检测时,则可以使用该设计模式。例如观察检测温度超过某阈值时,向APP推送短信提醒。
与MQTT协议的话题订阅推送其实是类似的,基本流程都是先订阅维护一个关系,在有状态变化时则给相应的观察者推送数据,唯一不同的是观察与被观察的关系是由谁来维护。