观察者模式适合的场景:
- 其作用在于:别的类 在某些数据有所变动的时候 能够及时的获取到这个变动;
- 适合一对多的依赖关系。
本文以此UML实例为例。
Subject
:
Subject
的意义:
- 用来存储变动的数据和数据的变动;
- 由上,使得变动的数据能及时的传达到需要的类(即
Observer
); Subject
在传达数据时,不需要关心接收者是否需要这次变动;Subject
在传达数据时,不要关系接收者的情况。Subject
必须提供的能力:
ArrayList<Observer> obArray;
//装载观察者(或称数据接收者)的容器;addObserver(Observer ob);
//提供向 容器 添加observer
的方法,此方法将在observer
里调用;notifyObservers();
//当数据变动时,在这里调用observer
们提供的方法,使得在这里提醒observer
们数据有所改动;removeObserver(Observer ob);
//提供从容器中删除这个 观察者 的方法,此方法将在observer
里被调用。接收数据的
Observer
:Observer
需要提供的能力:update();
//在subject中调用notifyObservers()
时,实质上就是调用observer.update()
来达到通知和更新observer
数据的效果;Subject subject;
//存储subject
,便于接下来的操作。
具体的Subject
实例:
使用接口,规定
subject
们的行为:public interface Subject {
public int addObserver(Observer Observer);
public int removeObserver(Observer Observer);
public int notifyObservers();
}
具体的
subject
实例:public class WeatherData implements Subject {
private ArrayList<Observer> observersList; //提供存储observer的容器
float temperature;
float humidity; //湿度
float pressure;
public WeatherData() {
observersList = new ArrayList<Observer>();
}
@Override
public int addObserver(Observer observer) { //提供给observer的加入自己这个容器的方法
observersList.add(observer);
return 0;
}
@Override
public int removeObserver(Observer observer) { //提供给observer的从容器中删除自己的方法
observersList.remove(observer);
return 0;
}
@Override
public int notifyObservers() { //提醒observer们,数据有变动。在此处,observer的数据也将被更新
for (Iterator<Observer> it = observersList.iterator(); it.hasNext(); ) {
it.next().update(temperature, humidity, pressure);
}
return 0;
}
private void DataChanged() {
notifyObservers();
}
public void setData(float temp, float hum, float pre) {
temperature = temp;
humidity = hum;
pressure = pre;
DataChanged();
}
}
具体的
Observer
实例:同样是先使用接口,规定
observer
们的行为:public interface Observer {
public void update(float temp, float hum, float press);
}
具体的
observer
实例:public class StatisticsDisplay implements Observer, DisplayBroad { //DisplayBroad是另外规定 显示 动作的接口,在此不体现
float temperature;
float humidity; //湿度
float pressure;
Subject weatherData; //存储具体的构造器
public StatisticsDisplay(Subject weatherData) { //本实例的具体subject将从构造器中传入
this.weatherData = weatherData;
weatherData.addObserver(this);
}
@Override
public void update(float temp, float hum, float pre) { //提供给subject中notify()操作的方法。在此实例中,被通知即进行数据更新
temperature = temp;
humidity = hum;
pressure = pre;
display();
}
@Override
public int display() { //其他行为
System.out.println("Statistics:" + temperature + "," + humidity + "," + pressure);
return 1;
}
}