观察者模式
观察者模式就是一对象或多个对象对另一外一个对象所处的不同状态可以随意的做出不同的反应。其中主要包含四个类:
抽象主题(Subject):提供接口,可以增加和删除观察者对象,又叫做抽象被观察者(Observable)角色
具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知
抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题的通知时更新自己
具体观察者(ConcreteObserver):具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态
类图
实例
Subject接口
public interface Subject { //注册 public void registerObserver(Observer o); //退出 public void removeObserver(Observer o); //发送数据 public void notifyObservers(); }
Observer接口
public interface Observer { //观察者接收信息,调用此方法更新自身数据 public void update(double temp,double humidity,double pressure); }
DisplayElement类,展示数据
public interface DisplayElement { //观察者调用此方法向用户显示数据 public void display(); }
WeatherData类(具体主题)
import java.util.ArrayList; public class WeatherData implements Subject{ private ArrayList observers; private double temperature; private double humidity; private double pressure; //初始化时,维护一个记录观察者的列表 public WeatherData() { observers = new ArrayList(); } //实现Subject接口的注册方法 public void registerObserver(Observer o) { observers.add(o); } //实现Subject接口的退出注册方法 public void removeObserver(Observer o) { int i = observers.indexOf(o); if(i>=0) { observers.remove(i); } } //实现Subject接口的notifyObservers(),用于向所有注册的观察者发送数据 public void notifyObservers() { for(int i=0;i) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } //有新数据时,向注册的观察者发送数据 public void measurementsChanged() { notifyObservers(); } //向获取数据的设备提供接口,当气象观察站获得新数据,会调用此接口向WeatherData写数据,以便WeatherData向观察者发送数据 public void setMeasurements(double temp,double humditidy,double pressure) { this.temperature = temp; this.humidity = humditidy; this.pressure = pressure; measurementsChanged(); } }
ConditionDisplay类:观察者类
public class ConditionDisplay implements Observer,DisplayElement{ private double temperature; private double humidity; private double pressure; private String name; private Subject weatherdata; //观察者初始化时,需要指定数据源和观察者的名字 public ConditionDisplay(Subject weatherdata,String name) { this.name = name; this.weatherdata = weatherdata; weatherdata.registerObserver(this); } //把数据打印 public void display() { System.out.println("观察者"+name+"的数据:"); System.out.println("temperature:"+temperature); System.out.println("humidity:"+humidity); System.out.println("pressure:"+pressure); System.out.println(); } //从数据源(WeatherData)获得数据后,用新数据更新自身数据 public void update(double temp, double humidity, double pressure) { this.temperature = temp; this.humidity = humidity; this.pressure = pressure; display(); } }
Test测试类
public class Test { public static void main(String[] args) { WeatherData weatherdata = new WeatherData(); //创建3个观察者 ConditionDisplay cd1 = new ConditionDisplay(weatherdata,"obser1"); ConditionDisplay cd2 = new ConditionDisplay(weatherdata,"obser2"); ConditionDisplay cd3 = new ConditionDisplay(weatherdata,"obser3"); //获得数据,并调用WeatherData的方法,来向WeatherData 写数据 weatherdata.setMeasurements(10.5, 10.4, 10.8); } }
运行结果为:
视频
链接:https://pan.baidu.com/s/1uT9PfCt6xOiRfYTm_cUAbQ
提取码:aocp