我们以一个老生常谈的例子来说明观察者模式——天气预报接口
第一步:天气预报一定有一个数据获取中心(姑且理解为气象局)
①气象局里面一定会有各个用户(网站)的注册信息(只有已经注册了人家气象局有气象数据变化了才能通知你嘛)-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