ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

java设计模式之观察者模式

2026/9/15 19:16:52 拓冰建站 浏览量
java设计模式之观察者模式

观察者模式(Observer Pattern)

基本介绍

  1. 观察者模式时一种行为型设计模式。
  2. 它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖着都会收到通知并自动更新。
  3. 当对象间存在一对多关系时,则使用观察者模式,比如一个对象被修改时,则会自动通知依赖它的对象。

应用实例

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

类图分析

分析

subject: 气象站 ,登记注册,移除,通知
Observer: 第三方网站。接收输入

代码实现:

//观察者接口,有观察者来实现
public interface Observer {public void update(float temperature, float pressure, float humidity);
}//接口, 让WeatherData 来实现 
public interface Subject {public void registerObserver(Observer o);public void removeObserver(Observer o);public void notifyObservers();
}/*** 类是核心* 1. 包含最新的天气情况信息 * 2. 含有 观察者集合,使用ArrayList管理* 3. 当数据有更新时,就主动的调用   ArrayList, 通知所有的(接入方)就看到最新的信息* @author Administrator**/
public class WeatherData implements Subject {private float temperatrue;private float pressure;private float humidity;//观察者集合private ArrayList<Observer> observers;//加入新的第三方public WeatherData() {observers = new ArrayList<Observer>();}public float getTemperature() {return temperatrue;}public float getPressure() {return pressure;}public float getHumidity() {return humidity;}public void dataChange() {//调用 接入方的 updatenotifyObservers();}//当数据有更新时,就调用 setDatapublic void setData(float temperature, float pressure, float humidity) {this.temperatrue = temperature;this.pressure = pressure;this.humidity = humidity;//调用dataChange, 将最新的信息 推送给 接入方 currentConditionsdataChange();}//注册一个观察者@Overridepublic void registerObserver(Observer o) {// TODO Auto-generated method stubobservers.add(o);}//移除一个观察者@Overridepublic void removeObserver(Observer o) {// TODO Auto-generated method stubif(observers.contains(o)) {observers.remove(o);}}//遍历所有的观察者,并通知@Overridepublic void notifyObservers() {// TODO Auto-generated method stubfor(int i = 0; i < observers.size(); i++) {observers.get(i).update(this.temperatrue, this.pressure, this.humidity);}}
}public class CurrentConditions implements Observer {// 温度,气压,湿度private float temperature;private float pressure;private float humidity;// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式public void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}// 显示public void display() {System.out.println("***Today mTemperature: " + temperature + "***");System.out.println("***Today mPressure: " + pressure + "***");System.out.println("***Today mHumidity: " + humidity + "***");}
}
public class BaiduSite implements Observer {// 温度,气压,湿度private float temperature;private float pressure;private float humidity;// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式public void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}// 显示public void display() {System.out.println("===百度网站====");System.out.println("***百度网站 气温 : " + temperature + "***");System.out.println("***百度网站 气压: " + pressure + "***");System.out.println("***百度网站 湿度: " + humidity + "***");}
}public static void main(String[] args) {//创建一个WeatherDataWeatherData weatherData = new WeatherData();//创建观察者CurrentConditions currentConditions = new CurrentConditions();BaiduSite baiduSite = new BaiduSite();//注册到weatherDataweatherData.registerObserver(currentConditions);weatherData.registerObserver(baiduSite);//测试System.out.println("通知各个注册的观察者, 看看信息");weatherData.setData(10f, 100f, 30.3f);weatherData.removeObserver(currentConditions);//测试System.out.println();System.out.println("通知各个注册的观察者, 看看信息");weatherData.setData(10f, 100f, 30.3f);}

运行结果:
结果

注意事项

好处:

  1. 观察者模式设计后,会以集合的方式来管理用户,包括注册,移除,通知。
  2. 这样,增加观察者,就不需要去修改核心类WeatherData不会修改代码,遵守了ocp原则。

缺点:

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。