前言
观察者,即时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协议的话题订阅推送其实是类似的,基本流程都是先订阅维护一个关系,在有状态变化时则给相应的观察者推送数据,唯一不同的是观察与被观察的关系是由谁来维护。