观察者模式
来源:互联网 发布:js 字符串转数组 编辑:程序博客网 时间:2024/06/08 12:09
定义
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
以气象站更新气象信息为例
// 主题接口public interface SubJect { void registerObserver(Observer o); void removeObserver(Observer o); void notifyObservers();}
// 气象站实现主题接口public class WeatherData implements SubJect { // 气象信息:温度,湿度,气压 private String temperature; private String humidity; private String pressure; // 观察者列表 private List<Observer> observers; public WeatherData() { this.observers = new ArrayList<Observer>(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { if(observers.indexOf(o)>0){ observers.remove(o); } } // 如何通知观察者,其实就是遍历本地的观察者列表,执行它们的update方法 @Override public void notifyObservers() { this.temperature = getTemperature(); this.humidity = getHumidity(); this.pressure = getPressure(); for(Observer o: observers){ o.update(temperature,humidity,pressure); } } public String getTemperature() { return temperature; } public String getHumidity() { return humidity; } public String getPressure() { return pressure; } /** * 气温有变化时立即调用 */ public void measureChanged(){ notifyObservers(); }}
// 观察者接口public interface Observer { void update(String temperature,String humidity,String pressure);}
// 这时一个气象统计布告,当气象信息变化时展示public class 气象统计 implements Observer{ // 本地气象信息 private String temperature; private String humidity; private String pressure; // 主题对象,用来注册自己 private SubJect weatherData; public 气象统计(SubJect weatherData) { this.weatherData = weatherData; // 初始化的时候注册自己 weatherData.registerObserver(this); } // 实现update方法,一旦气象信息变化了,主题会调用该方法 @Override public void update(String temperature, String humidity, String pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; this.display(); } @Override public void display() { System.out.println(toString()); } @Override public String toString() { return "气象统计{" + "temperature='" + temperature + '\'' + ", humidity='" + humidity + '\'' + ", pressure='" + pressure + '\'' + '}'; }}
其实java内置了观察者模式,但是有些内容和上述略有不同,但是都是情理之中。下面一一解释
区别一:
jdk自带的观察者模式中,被观察者接口是Observer
Observer有方法setChanged(),是将一个全局变量变为true,为什么呢?
protected synchronized void setChanged() { changed = true; }
显然,当没有变的时候,是不更新的。那么“变”到底指的是什么?其实是对事实的控制,比如说温度,如果精确单位是千分之一,那岂不是温度时时刻刻都在变化,这样更新太频繁了。我们只有当它的温度变化超过一度,才会setChanged(),这时候才会真的通知所有观察者
public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); }
区别二:update方法的参数,理应是Obj对象,而不是自定义的。
update有两个参数,一个是带个Observer的数据,一个是主题本身
@Override public void update(Observable o, Object arg) { if(o instanceof WeatherData){ this.temperature = ((WeatherData) o).getTemperature(); this.humidity = ((WeatherData) o).getHumidity(); this.pressure = ((WeatherData) o).getPressure(); display(); } }
0 0
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- Kafka剖析(一):Kafka背景及架构介绍
- Linux命令文档的管理和权限的使用
- Python 标准输出 sys.stdout 重定向
- Codeforces 624C Graph and String
- ANR完全解析
- 观察者模式
- LoginPage的实现
- datatable 异步加载
- jsp获取请求参数一些常见的方法
- POJ NOI MATH-7647 余数相同问题
- 链表划分
- Apache Kafka:下一代分布式消息系统
- 求数组中最长递增子序列,数组分割,数组循环移位,区间重合判断
- vi编辑器的初步使用