我们以一个老生常谈的例子来说明观察者模式——天气预报接口
第一步:天气预报一定有一个数据获取中心(姑且理解为气象局)
①气象局里面一定会有各个用户(网站)的注册信息(只有已经注册了人家气象局有气象数据变化了才能通知你嘛)-registerObserver
②气象局里面一定有一个移除某个用户(网站)的方法-removeObserver
③气象局里面一定有一个通知各个用户(网站)关于气象数据的方法-notifyObservers
第二步:另外,因为用户(网站也可以叫观察者)一定是有多个的,所以这个一定会被设计成一个抽象类或者是接口(我自己是这么理解的),为了体现面向接口编程,我们就设计成接口MyObserver
①MyObserver里面一定有一个方法update,用户(网站)/观察者,需要根据中心的的数据来更新自己的数据
第三步:开始撸代码
气象中心接口:Subject.java
1 //接口让WeatherData来实现,它的实现类需要聚合观察者
2 public interface Subject {
3 //注册观察者
4 void registerObserver(MyObserver o);
5 //移除观察者
6 void removeObserver(MyObserver o);
7 //通知观察者
8 void notifyObserver();
9 }
气象中心接口实现类WeatherData.java
1 package com.example.demo.designmodel.observer.improve;
2
3 import com.example.demo.designmodel.observer.CurrentConditions;
4
5 import java.util.ArrayList;
6 import java.util.List;
7
8 /**
9 * 类是核心
10 * 1. 包含最新的天气情况信息
11 * 2. 含有观察者集合
12 * 3. 当数据有更新时,就主动的调用 ArrayList通知所有的接入方
13 *
14 * @author miles zhu
15 */
16 public class WeatherData implements Subject {
17 //气温
18 private float temperatrue;
19 //气压
20 private float pressure;
21 //湿度
22 private float humidity;
23
24 //定义一个集合,用于存放所有的观察者
25 //因为观察者不可能只有一个
26 private List<MyObserver> observersList;
27
28 private CurrentConditions currentConditions;
29 //加入新的第三方
30
31 public WeatherData() {
32 observersList = new ArrayList<>();
33 }
34
35
36 //这个方式实际上是用来管理观察者的
37 public void dataChange() {
38 //调用 接入方的 update
39 notifyObserver();
40 }
41
42 //当数据有更新时,就调用 setData
43 public void setData(float temperature, float pressure, float humidity) {
44 this.temperatrue = temperature;
45 this.pressure = pressure;
46 this.humidity = humidity;
47 //调用dataChange, 将最新的信息 推送给 接入方 currentConditions
48 dataChange();
49 }
50
51 //添加一个观察者
52 @Override
53 public void registerObserver(MyObserver o) {
54 observersList.add(o);
55 }
56
57 //移除一个观察者
58 @Override
59 public void removeObserver(MyObserver o) {
60 if (observersList.contains(o)) {
61 observersList.remove(o);
62 }
63 }
64
65 //通知观察者
66 @Override
67 public void notifyObserver() {
68 for (int i = 0; i < observersList.size(); i++) {
69 observersList.get(i).update(this.temperatrue, this.pressure, this.humidity);
70 }
71 }
72
73 //get方法
74 public float getTemperature() {
75 return temperatrue;
76 }
77
78 public float getPressure() {
79 return pressure;
80 }
81
82 public float getHumidity() {
83 return humidity;
84 }
85 }
观察者接口MyObserver.java
1 package com.example.demo.designmodel.observer.improve;
2
3 //观察者接口,由观察者实现
4 public interface MyObserver {
5 //观察者模式的核心方法
6 void update(float temperature, float pressure, float humidity);
7 }
某个实现类CurrentConditions.java
1 package com.example.demo.designmodel.observer.improve;
2
3 /**
4 * 文件名:CurrentConditions
5 * 作 者:Miles zhu
6 * 时 间:2019/7/30 17:04
7 * -------------------------
8 * 功能和描述:
9 **/
10 public class CurrentConditions implements MyObserver{
11 private float tempurature;
12 private float pressure;
13 private float humidity;
14
15 @Override
16 public void update(float tempurature, float pressure, float humidity) {
17 this.tempurature = tempurature;
18 this.pressure = pressure;
19 this.humidity = humidity;
20 display();
21 }
22
23 public void display() {
24 System.out.println("tempurature============" + tempurature);
25 System.out.println("pressure============" + pressure);
26 System.out.println("humidity============" + humidity);
27 }
28 }
搞定,先爽一下呗?测试类Client.java
1 package com.example.demo.designmodel.observer.improve; 2 3 /** 4 * 文件名:Client 5 * 作 者:Miles zhu 6 * 时 间:2019/7/30 17:30 7 * ------------------------- 8 * 功能和描述: 9 **/ 10 public class Client { 11 public static void main(String[] args) { 12 //创建一个WeatherData 13 WeatherData weatherData = new WeatherData(); 14 //创建一个观察者 15 CurrentConditions currentConditions = new CurrentConditions(); 16 //将观察者注册到weatherdata 17 weatherData.registerObserver(currentConditions); 18 weatherData.setData(30.f,150f,10f); 19 } 20 }
然后又加入了一个观察者Baidu.java
1 package com.example.demo.designmodel.observer.improve; 2 3 /** 4 * 文件名:Client 5 * 作 者:Miles zhu 6 * 时 间:2019/7/30 17:30 7 * ------------------------- 8 * 功能和描述: 9 **/ 10 public class Client { 11 public static void main(String[] args) { 12 //创建一个WeatherData 13 WeatherData weatherData = new WeatherData(); 14 //创建一个观察者 15 CurrentConditions currentConditions = new CurrentConditions(); 16 //将观察者注册到weatherdata 17 weatherData.registerObserver(currentConditions); 18 19 //将Baidu添加进去----新添加的Baidu这个观察者 20 Baidu baidu = new Baidu(); 21 weatherData.registerObserver(baidu); 22 23 weatherData.setData(30.f,150f,10f); 24 } 25 }
输出:
OVER