观察者模式
来源:互联网 发布:淘宝里的优惠券怎么用 编辑:程序博客网 时间:2024/04/26 02:46
(本文中一些例子和定义均摘自《Head First 设计模式》)
“观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态的时候,它的所有依赖者都会收到通知并自动更新。”
举例,天气情况报告。
我们有很多不同的表示天气预报的公告栏,当天气情况发生变化的时候,这些公告栏都能够接收到变化的通知,并且自动的根据变化而变化。
当观察者不需要再订阅主题的时候,能够退订主题。这样天气预报变化的情况就不会再通知它。
步骤:
1. 主题接口
//注册观察者
public void registerObserver(Observer o);
//注销观察者
public void removeObserver(Observer o);
//通知所有的观察者
public void notifyObservers();
}
2. 观察者接口
//对主题的变化情况,做更新
public void update(float temperature, float humidity, float pressure);
}
3. 显示接口
//观察者通过此接口来显示信息
public void display();
}
4. 对具体的主题,实现主题接口
public class WeatherData implements Subject ...{
@SuppressWarnings("unchecked")
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
@SuppressWarnings("unchecked")
public WeatherData() ...{
observers = new ArrayList();
}
@Override
public void notifyObservers() ...{
for(int i = 0; i < observers.size(); i++) ...{
Observer observer = (Observer)observers.get(i);
observer.update(temperature, humidity, pressure);
}
}
@SuppressWarnings("unchecked")
@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);
}
}
public void measurementsChanged() ...{
notifyObservers();
}
public void setMeasurements(float temperure, float humidity, float pressure) ...{
this.temperature = temperure;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
5. 建立布告栏,也就是我们的观察者,实现观察者接口
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) ...{
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) ...{
this.temperature = temperature;
this.humidity = humidity;
//display();
}
@Override
public void display() ...{
System.out.println("Current conditions: " + temperature + " F degree and " + humidity + " % humidity");
}
}
这样整个基本的模型就搭建完成。接下来测试一下
public static void main(String[] args) ...{
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(100, 80, 90);
currentDisplay.display();
}
}
可以发现,当主题(weatherData)发生变化的时候,观察者(currentDisplay)收到变化的通知,并且随着主题的变化而变化。
JAVA内置的观察者模式
一个被观测的对象必须服从下面的两个简单规则。第一,如果它被改变了,它必须调用setChanged( )方法。第二,当它准备通知观测程序它的改变时,它必须调用notifyObservers( )方法。这导致了在观测对象中对update( )方法的调用。注意——当对象在调用notifyObservers( )方法之前,没有调用setChanged( )方法,就不会有什么动作发生。在update( )被调用之前,被观测对象必须调用setChanged( )和notifyObservers( )两种方法
private float temperature;
private float humidity;
private float pressure;
……..
public void measurementsChanged() ...{
setChanged();
notifyObservers(float temperature);
}
}
private float temperature;
private float humidity;
private float pressure;
……..
public void update(Observable obs,Object arg) ...{
if(arg instanceof Float)...{
temperature = ((Float)arg).floatValue();
}
}
而第二种不带参数的notifyObservers(),当调用它的时候, 传递一个null的数据对象给观察者.
private float temperature;
private float humidity;
private float pressure;
……..
public void measurementsChanged() ...{
setChanged();
notifyObservers();
}
public float getTemperature()...{
Return temperature;
}
}
private float temperature;
private float humidity;
private float pressure;
……..
public void update(Observable obs,Object arg) ...{
if(obs instanceof WeatherData)...{
WeatherData weatherData = (WeatherData)obs;
This.temperature = weatherData.getTemperature();
}
}
JAVA内置观察者模式不足之处:
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- VC常用技巧总结
- 脚本实现vi/cp/mv前自动备份源文件
- 自己写的.net分页控件,测试没有问题!
- WebSphere 应用服务器 6.1 Web Services 功能部件包入门
- 蒙牛内幕连载
- 观察者模式
- 告别“前门大街”(图文)
- 李嘉诚家族关系内幕
- 转载分页控件
- 解构李嘉诚亡妻坟墓被盗内幕
- 【话题】Flash IDE 开发者面临FLEX的挑战
- 脚本实现自动检测到多台主机的网络连通性
- [学习笔记]字符集编码
- 使用 NIM 跨网段安装 AIX