概述
观察者模式
观察者模式 定义了对象之间的一对多依赖。举个例子,报纸订阅服务就是一个观察者模式的例子,当某人订阅了报纸后,当新的报纸出来(数据发生变化)时,就会讲报纸发送给所有的订阅者,报纸和订阅者是一对多的依赖。观察者模式中,当一个对象改变状态时,它的所有依赖着都会收到通知并自动更新。
应用实例:设计一个简单的气象监测应用
气象站:获取实际气象数据
WeatherData对象:追踪来自气象站的数据,并更新布告板
布告板:显示天气状况给用户看(有很多不同布告板)
设计类图:
实现代码:
主题接口:Subject
public interface Subject {
public void registerObserver(Observer o); //向观察者集合中添加观察者o
public void removeObserver(Observer o); //从集合中移除观察者o
public void notifyObserver(); //自动更新/通知
}
WeatherData类实现Subject接口
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(i);
}
}
//自动更新/通知
@Override
public void notifyObserver() {
// 从集合中获取所有观察者对象, 依次执行该对象的update方法更新布告板
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer) observers.get(i);
observer.update(temperature, humidity, pressure);
}
}
// WeatherData对象获得来自气象站的数据, 并更新布告板
public void setMesurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged(); // 数据发生改变时执行
}
// 调用更新方法, 更新布告板
public void measurementsChanged() {
notifyObserver();
}
}
观察者接口:Observer
public interface Observer {
public void update(float temp, float humidity, float pressure);
}
显示接口:DisplayElement
public interface DisplayElement {
public void display();
}
实现观察者接口的观察者类(1)
public class CurrentConditionsDisplay implements Observer ,DisplayElement{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData; //通过构造器获取weatherData对象
//使用该weatherData对象的registerOberver方法将当前对象添加到观察者集合中
this.weatherData.registerObserver(this);
}
//更新
@Override
public void update(float temp, float humidity, float pressure) {
// TODO Auto-generated method stub
this.temperature = temp;
this.humidity = humidity;
display();
}
//显示
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("Current conditions: "+ temperature + "F degrees and " + humidity + "% humidity " );
}
}
观察者类(2)
package com.promote1996.demo;
public class DemoDisplay implements Observer, DisplayElement {
private float pressure;
private Subject weatherData;
public DemoDisplay(Subject weatherData) {
this.weatherData = weatherData; //通过构造器获取weatherData对象
//使用该weatherData对象的registerOberver方法将当前对象添加到观察者集合中
this.weatherData.registerObserver(this);
}
//显示
@Override
public void display() {
System.out.println("The pressure is "+ pressure +" Pa");
}
//更新
@Override
public void update(float temp, float humidity, float pressure) {
this.pressure = pressure;
display();
}
}
测试类
public class TestDemo {
public static void main(String [] args) {
WeatherData weatherData = new WeatherData(); //新建一个weatherData的实例
//通过观察者的构造器将该weatherData对象传递给观察者
new CurrentConditionsDisplay(weatherData);
new DemoDisplay(weatherData);
//测试数据
weatherData.setMesurements(10, 20, 30);
weatherData.setMesurements(150, 39, 100);
}
}
测试结果
代码执行流程小结
- 创建主题对象,用接口声明;
- 调用接口的add方法,将对象添加到观察者集合中,即对象注册为观察者;
- 当主题发生变化,主题从集合中遍历出所有观察者,并依次调用所有观察者的同一个方法,每一个观察者都会执行自己重写父类的方法。
总结:
当主题发生变化,观察者才做出相应变化。观察者模式类似于动态为某接口添加实现类,重写父类的方法。当主题发生变化,观察者类都会执行自己覆盖接口中的方法。
有什么不对的地方还请多多指教。
最后
以上就是个性冷风为你收集整理的观察者模式总结的全部内容,希望文章能够帮你解决观察者模式总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复