介绍
多个其他类想对某一个类的属性实现同步时使用
原理
对原理类图的说明-即(命名模式的角色及职责)
- Subject接口目的是管理观察者,registerObserver注册观察者,removeObserver移除观察者,notifyObservers通知观察者
- 数据源类就是观察者观察的目标,数据源需要提前把观察者注册到observers集合中,当数据源类数据更新时,能自身通知各个观察者或者提供接口让观察者调用查看最新数据。
- Observer是观察者的一个抽象接口,update方法是当数据源信息更新时,同步到观察者上的数据的方法
案例
天气预报项目需求,具体要求如下:
- 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。
- 需要设计开放型API,便于其他第三方也能接入气象站获取数据。
- 提供温度、气压和湿度的接口
- 测量数据更新时,要能实时的通知给第三方

//Subject三个方法都是操作的观察者集合的public interface Subject {public void registerObserver(Observer o);public void removeObserver(Observer o);public void notifyObservers();}//WeatherData(天文台)实现Subject实现操作观察者的方法public class WeatherData implements Subject{private double temperature;private double pressure;private double humidity;private ArrayList<Observer> observers = new ArrayList<>();public double getTemperrature() {return temperature;}public double getPressure() {return pressure;}public double getHumidity() {return humidity;}public void dataChange(){notifyObservers();}public void setWeatherData(double temperature,double pressure,double humidity){this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;dataChange(); //通知观察者数据改变}@Overridepublic void registerObserver(Observer o) {observers.add(o);}@Overridepublic void removeObserver(Observer o) {if (observers.contains(o)){observers.remove(o);}}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(this.temperature,this.pressure,this.humidity);}}}
//抽象观察者接口public interface Observer {public void update(double temperature,double pressure,double humidity);}//新浪观察者实现类public class xinlang implements Observer{private double temperature;private double pressure;private double humidity;@Overridepublic void update(double temperrature, double pressure, double humidity) {this.temperature = temperrature;this.pressure = pressure;this.humidity = humidity;display();}private void display() {System.out.println("新浪-------温度为 "+ temperature + "度--------");System.out.println("新浪-------气压为 "+ pressure + "帕--------");System.out.println("新浪-------湿度为 "+ humidity + "%--------");}}//百度观察者实现类public class Baidu implements Observer{private double temperature;private double pressure;private double humidity;@Overridepublic void update(double temperrature, double pressure, double humidity) {this.temperature = temperrature;this.pressure = pressure;this.humidity = humidity;display();}private void display() {System.out.println("百度-------温度为 "+ temperature + "度--------");System.out.println("百度-------气压为 "+ pressure + "帕--------");System.out.println("百度-------湿度为 "+ humidity + "%--------");}}
//Client端测试public class Client {public static void main(String[] args) {//创建WeatherData天气数据对象WeatherData weatherData = new WeatherData();//创建观察者Observer observer1 = new Baidu();Observer observer2 = new xinlang();//注册观察者weatherData.registerObserver(observer1);weatherData.registerObserver(observer2);//天文台数据改变weatherData.setWeatherData(30,150,60);}}
观察者模式的好处
- 观察者模式设计后,会以集合的方式来管理用户(Observer),包括注册,移除和通知。
- 这样,我们增加观察者(这里可以理解成一个新的公告板),就不需要去修改核心类WeatherData不会修改代码,遵守了ocp原则。
个人总结
此模式的核心是使用一个接口把全部观察者统一接管了,再在数据源类中用集合统一管理所有观察者,核心的方法是
1.注册观察者
2.移除观察者
3.通知所有观察者
