定义
观察者模式定义了对象之间的一对多依赖,这样当一个对象(称为主题)改变状态时,它的所有依赖者(称为观察者)都会收到通知并自动更新。
类图
![](https://img.haomeiwen.com/i3623514/42537043481198d1.jpg)
其中所涉及到的对象有:
- 抽象主题(Subject)接口:将观察者对象引用存放在一个集合里(例如ArrayList),封装了对观察者的一些行为方法,可以进行观察者的注册(添加对象)、删除以及唤醒(向观察者送出通知)。
- 具体主题(ConcreteSubject):掌握一些数据,实现了主题接口中对观察者的操作方法。
- 抽象观察者(Observer)接口:为所有具体的观察者定义了一个接口,在接到主题通知时,更新自己。
- 具体观察者(ConcreteObserver):包含了主题对象的引用,当主题对象改变时,利用update()方法更新自己。
实例
建设一个气象站,其中包括气象观测站以及天气布告板。气象观测站有天气的各项参数,它将参数推送给布告板让其显示天气参数。
代码:
public interface Subject{//抽象主题类
public abstract void registerObserver(Observer observer);
public abstract void removeObserver(Observer observer);
public abstract void notifyObservers();
}
public class WeatherData implements Subject{//具体主题类
ArrayList<Observer> observers;
private float temerature;
private float humidity;
private float pressure;
public WeatherData(){
observers=new ArrayList<Observer>();
}
public void registerObserver(Observer observer){//添加观察者
observers.add(observer);
}
public void removeObserver(Observer observer){//删除观察者
observers.remove(observer);
}
public void notifyObservers(){//向观察者推送更新
for(int i=0;i<observers.size();i++){
Observer o=observers.get(i);
o.update(temperature,humidity,pressure);
}
}
public void measurementsChanged(){//客户端调用该方法观测更新
notifyObservers();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
measurementsChanged()
}
public interface Observer{//观察者接口
abstract void update(float temperature,float humidity,float pressure);
}
public class Display implements Observer{//具体观察者类
private float temperature;
private float humidity;
private float pressure;
Subject subject;
public Display(Subject subject){
this.subject=subject;
}
public void update(float temp,float humidity,float pressure){
this.temperature=temp;
this.humidity=humidity;
this.pressure=pressure;
display();
}
public void display(){
//实现显示
}
}
public class Client{//客户端
public static void main(String[] args){
WeatherData weatherData=new WeatherData();//创建主题对象
Display display=new Display(weatherData);//创建观察者对象,并与对应主题关联
weatherData.setMeasurements(80,65,30f);//设置更新数据,此时已经向观察者推送了更新同时观察者收到了更新。
}
}
扩展
- 可以在主题中加入标记主题状态是否更改的变量,以便更好地给观察者推送更新
- 以上介绍的观察者模式中只有主题将自己所有的数据都推送给观察者,不管观察者是否需要。可以加入观察者自己“拉”数据的模式,只获取其有用的数据。即在主题中加入返回数据的方法
- java JDK中提供了观察者模式的接口,其为java.util包中的Observable(主题)类和Observer接口,该模式提供了“推”和“拉”数据两种方法。
- 观察者模式实现了主题和对象之间的松耦合,即它们彼此可以交互,但是不清楚彼此的细节。
网友评论