案例

天气预报项目需求,具体要求如下:
1) 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如
发布到自己的网站或第三方)。
2) 需要设计开放型API,便于其他第三方也能接入气象站获取数据。
3) 提供温度、气压和湿度的接口
4) 测量数据更新时,要能实时的通知给第三方

传统方案

image.png 或者
image.png
问题:
其他第三方接入气象站获取数据的问题
无人发在运行时动态加入
违反ocp

观察者模式

观察者模式累死订牛奶业务
奶站/气象站 Subject
用户/气象站 Observer

image.png

1) registerObserver 注册
2) removeObserver 移除
3) notifyObservers() 通知所有的注册的用户,根据不同需求,可以是更新数据,让用
户来取,也可能是实施推送,看具体需求定

image.png

image.png

  1. public class Subject extends Observable {
  2. private float temperature;
  3. private float pressure;
  4. private float humidity;
  5. public void setData(float temperature,
  6. float pressure,
  7. float humidity){
  8. this.temperature = temperature;
  9. this.pressure = pressure;
  10. this.humidity = humidity;
  11. setChanged();
  12. notifyObservers(this);
  13. }
  14. @Override
  15. public String toString() {
  16. return "Subject{" +
  17. "temperature=" + temperature +
  18. ", pressure=" + pressure +
  19. ", humidity=" + humidity +
  20. '}';
  21. }
  22. }
  1. public class CurrentCondition implements Observer {
  2. private float temperature;
  3. private float pressure;
  4. private float humidity;
  5. @Override
  6. public void update(Observable o, Object arg) {
  7. Subject subject = (Subject)arg;
  8. System.out.println("change 1" + subject.toString());
  9. }
  10. }
  11. public class Baidu implements Observer {
  12. private float temperature;
  13. private float pressure;
  14. private float humidity;
  15. @Override
  16. public void update(Observable o, Object arg) {
  17. Subject subject = (Subject)arg;
  18. System.out.println("baidu 1" + subject.toString());
  19. }
  20. }
  1. public static void main(String[] args) {
  2. Subject subject = new Subject();
  3. subject.addObserver(new CurrentCondition());
  4. subject.addObserver(new Baidu());
  5. subject.setData(1,2,3);
  6. }