一、观察者模式(Observer)原理
1、观察者模式原理
观察者模式类似于订牛奶业务:
(1)奶站/气象局:Subject;
(2)用户/第三方网站:Observer
Subject:登记注册、移除和通知
(1)registerObserver 注册
(2)removeObserver 移除
(3)notifyObserver() 通知所有的注册的用户,根据不同需求,可以是更新数据,让用户来取,也可能是实施推送,看具体需求;
Observer:接收输入
观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为 Subject,依赖的对象为 Observer,Subject 通知 Observer 变化,比如这里的奶站是 Subject,是 1 的一方,用户是 Observer,是多的一方。
二、观察者模式应用
1、思路分析图解(类图)
2、代码实现
Subject接口
1 /**
2 * 接口,让 WeatherData 来实现
3 */
4 public interface Subject {
5
6 public void registerObserver(Observer o);
7 public void removeObserver(Observer o);
8 public void notifyObserver();
9 }
Subject实现类:
1 /**
2 * 核心类
3 * 1、包含最新的天气情况信息
4 * 2、包含 观察者集合,使用 ArrayList 管理
5 * 3、当数据有更新时,就主动的调用 ArrayList,
6 * 通知所有(接入方)就看到最新的信息
7 *
8 */
9 public class WeatherData implements Subject{
10
11 private float temperatrue;
12 private float pressure;
13 private float humidity;
14
15 //观察者集合
16 private ArrayList<Observer> observers;
17
18 public WeatherData() {
19 this.observers = new ArrayList<>();
20 }
21
22 /**
23 * 注册一个观察者
24 * @param o
25 */
26 @Override
27 public void registerObserver(Observer o) {
28 observers.add(o);
29 }
30
31 /**
32 * 移除一个观察者
33 * @param o
34 */
35 @Override
36 public void removeObserver(Observer o) {
37 if (observers.contains(o)) {
38 observers.remove(o);
39 }
40 }
41
42 //遍历所有的观察者,并通知
43 @Override
44 public void notifyObserver() {
45 for (int i = 0; i < observers.size(); i++) {
46 observers.get(i).update(temperatrue, pressure, humidity);
47 }
48 }
49
50
51 /**
52 * 当数据有更新时就调用 setData
53 * @param temperature
54 * @param pressure
55 * @param humidity
56 */
57 public void setData(float temperature, float pressure, float humidity) {
58 this.temperatrue = temperature;
59 this.pressure = pressure;
60 this.humidity = humidity;
61 //调用 dataChange 方法,将最新信息 推送给 接入方 currentConditions
62 dataChange();
63 }
64
65 //通知所有
66 public void dataChange() {
67 notifyObserver();
68 }
69
70
71 public float getTemperatrue() {
72 return temperatrue;
73 }
74
75 public void setTemperatrue(float temperatrue) {
76 this.temperatrue = temperatrue;
77 }
78
79 public float getPressure() {
80 return pressure;
81 }
82
83 public void setPressure(float pressure) {
84 this.pressure = pressure;
85 }
86
87 public float getHumidity() {
88 return humidity;
89 }
90
91 public void setHumidity(float humidity) {
92 this.humidity = humidity;
93 }
94
95 public ArrayList<Observer> getObservers() {
96 return observers;
97 }
98
99 public void setObservers(ArrayList<Observer> observers) {
100 this.observers = observers;
101 }
102 }
观察者接口Observer:
1 /**
2 * 观察者接口,由观察者来实现
3 */
4 public interface Observer {
5
6 public void update(float temperatrue, float pressure, float humidity);
7 }
观察者实现类:
1 public class CurrentConditions implements Observer{
2 private float temperature; //温度
3 private float pressure; //气压
4 private float humidity; // 湿度
5
6
7 /**
8 * 更新天气情况,是由 WeatherData 来调用,使用的是 推送模式
9 * @param temperature
10 * @param pressure
11 * @param humidity
12 */
13 @Override
14 public void update(float temperature, float pressure, float humidity) {
15 this.temperature = temperature;
16 this.pressure = pressure;
17 this.humidity = humidity;
18 display();
19 }
20
21
22 /**
23 * 显示信息
24 */
25 public void display() {
26 System.out.println("***Today mTemperature: " + temperature + "***");
27 System.out.println("***Today mPressure: " + pressure + "***");
28 System.out.println("***Today mHumidity: " + humidity + "***");
29 }
30 }
31
32 --------------------------------------------------
33 public class BaiduSite implements Observer{
34
35 private float temperature; //温度
36 private float pressure; //气压
37 private float humidity; // 湿度
38
39 @Override
40 public void update(float temperatrue, float pressure, float humidity) {
41 this.temperature = temperature;
42 this.pressure = pressure;
43 this.humidity = humidity;
44 display();
45 }
46
47 /**
48 * 显示信息
49 */
50 public void display() {
51 System.out.println("***百度天气信息***");
52 System.out.println("***百度网站:Today mTemperature: " + temperature + "***");
53 System.out.println("***百度网站:Today mPressure: " + pressure + "***");
54 System.out.println("***百度网站:Today mHumidity: " + humidity + "***");
55 }
56 }
客户端:
1 public class Client {
2 public static void main(String[] args) {
3
4 //1.创建 WeatherData
5 WeatherData weatherData = new WeatherData();
6
7 //2.创建观察者
8 CurrentConditions currentConditions = new CurrentConditions();
9
10 //3.注册到 weatherData 中
11 weatherData.registerObserver(currentConditions);
12
13
14 //再次创建观察者
15 BaiduSite baiduSite = new BaiduSite();
16 weatherData.registerObserver(baiduSite);
17
18 //4.测试
19 System.out.println("通知各个注册的观察者,看看信息");
20
21 weatherData.setData(10, 100, 30.3f);
22
23
24 }
25 }
三、观察者模式的好处
1、观察者模式设计后,会以集合的方式来管理用户(Observer),包括注册,移除和通知;
2、这样,我们增加观察者(这里可以理解成一个新的公告板),就不需要去修改核心类 WeatherData 不会修改代码,遵守了 OCP 原则;