观察者模式:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新
发布者(发布数据)——观察者1(接收数据)
发布者(发布数据)——观察者2(接收数据)
在这里举例:
发布者:比喻为 气象局,
观察者:墨迹天气(观察者1)、雅虎天气(观察者2)
气象局用仪器设备能采集到天气的 温度、湿度、气压
而墨迹天气、雅虎天气需要交钱成为会员,在气象局注册,气象局才会给他们俩推送数据
气象局采集的温度、湿度、气压一改变,就得通知墨迹天气、雅虎天气
如果墨迹天气不给气象局交钱,气象局就得把墨迹天气删掉,不再给他推送数据
(理解就好,不要在意语病)
代码来了:
1、发布者(气象局)推送天气数据需要实现的功能——接口
(1)能让各种天气软件注册为会员
(2)不交钱,就删除他们
(3)气象局实时采集到新的数据,就推送给会员们
package Observer;
public interface Subject {
//注册观察者
public void registerObserver(Observer o);
//删除观察者
public void removeObserver(Observer o);
//当主题状态改变时,此方法被调用,来通知所有的观察者
public void notifyObservers();
}
2、观察者得到的更新的数据——接口
package Observer;
/*
* 所有观察者都必须实现update()方法,以实现观察者接口
*
*/
public interface Observer {
//当气象观测值改变时,主题会把这些状态值当作方法的参数,传给观察者
public void update(float temperature , float humidity, float pressure);
}
3、墨迹天气(观察者1)和雅虎天气(观察者2)都要显示从气象局得到的数据,这里单独提个接口,就是要让观察者必须实现display()方法,省的到时候忘了实现
package Observer;
public interface DisplayElement {
//当布告板需要显示时,调用此方法
public void display();
}
4、发布者(气象局)推送天气数据的功能实现类
package Observer;
import java.util.ArrayList;
public class WeatherData implements Subject{
private ArrayList observers; //观察者集合
private float temperature; //温度
private float humidity; //湿度
private float pressure; //气压
public WeatherData(){
observers = new ArrayList();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(o);
}
}
@Override
public void notifyObservers() {
for (int i = 0; i<observers.size(); i++) {
Observer observer = (Observer) observers.get(i);
observer.update(temperature, humidity, pressure);
}
}
//数据改变,通知所有观察者
public void setMeasurements(float temperature, float humidity, float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public void measurementsChanged(){
notifyObservers();
}
}
5、观察者(墨迹天气、雅虎天气等)接收数据并显示的功能实现类
package Observer;
/*
* 观察者1:
* 实现了Observer接口,可以从WeatherData对象中获得改变
* 实现了DisplayElement接口,因为布告板都要展示数据,必须实现,防止忘记实现
*/
public class CurrentConditionsDisplay implements Observer, DisplayElement{
private float temperature; //温度
private float humidity; //湿度
private float pressure; //气压
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this); //注册当前观察者(this),Weather的ArrayList就添加了此观察者
}
@Override
public void display() {
System.out.println("温度:" + temperature + "\n" + "湿度:" + humidity + "\n" + "气压:" + pressure);
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display(); //值改变的时候就display()显示数据
}
}
可以建立更多的观察者,display()不同的内容
6、Main方法:测试类
package Observer;
public class Main {
public static void main(String[] args) {
//建立WeatherData对象
WeatherData weatherData = new WeatherData();
//建立一个观察者(布告板),用来显示从主题获得的数据
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
//可以建立更多的观察者,display()不同的内容
weatherData.setMeasurements(50, 40, 30);
//数据实时改变,就会输出最新的数据
weatherData.setMeasurements(88, 77, 66);
}
}