观察者(Observer)模式
来源:互联网 发布:linux snmp trap 接收 编辑:程序博客网 时间:2024/05/17 14:29
HeadFirst设计模式读书笔记
观察者模式
一,简介
- 什么是观察者模式?
定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。
理解:类似于报纸订阅,向某家报社(被观察者)订阅报纸,只要有新报纸出版,他就会把新报纸送到订阅者(观察者)手中。同时订阅者可以取消订阅这份报纸。 - 现在还是书中的例子:被观察者是气象数据WeatherData,观察者是气象显示板CurrentConditionDisplay,类图如下:
二,自定义观察者模式代码实现
1,三个接口如下:
public interface Subject { public void registerObserver(Observer o);}public interface Observer { public void update(float temp,float humidity,float pressure);}public interface DisplayElement { public void display();}
2,WeatherData的实现
package implementObjObserver;import java.util.ArrayList;import interfaces.Observer;import interfaces.Subject;public class WeatherData implements Subject{ private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers = new ArrayList(); } public void removeObserver(Observer o){ int i = observers.indexOf(o); if(i>=0){ observers.remove(i); } } public void notifyObservers(){ for(int i = 0; i < observers.size(); i++){ Observer observer =(Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } @Override public void registerObserver(Observer o) { // TODO Auto-generated method stub observers.add(o); } public void setMeasurements(float temperature,float humidity,float pressure){ this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } public void measurementsChanged(){ notifyObservers(); }}
3,CurrentConditionDisplay代码如下
package implementObjObserver;import interfaces.DisplayElement;import interfaces.Observer;import interfaces.Subject;public class CurrentConditionsDisplay implements Observer,DisplayElement { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) { // TODO Auto-generated constructor stub this.weatherData = weatherData; 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"); }}
4,测试代码
package implementObjObserver;public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80, 12, 20.4f); }}
三,JDK中的观察者模式
1,简介
jdk中内置了观察者模式,但是Observable是一个类不是一个接口,那么久降低了其扩展性,因为一个类只能继承一个类。
2,需要注意的部分
- 增加了一个setChanged方法。
- 两种通知观察者的方式:
- notifyObservers();采用这种方式,观察者需要用拉的方式获取更新(在下面的代码中可以看到)
- notifyObservers(Object obj);这是一种推数据的方式,直接将一个object对象通知给每一个观察者。
四,使用JDK封装的观察者模式实现代码
1,不需要提供observer和observable接口,只需要提供一个每个显示板都需要实现display方法的接口
public interface DisplayElement { public void display();}
2,WeatherData需要继承jdk提供的Observable类,其中注册observer的list以及notifyObserver()具体的实现都已经被jdk内部实现好了。
package com.liu;import java.util.Observable;public class WeatherData extends Observable { private float temperature; private float humidity; private float pressure; public void messureChanged(){ setChanged(); notifyObservers(); } public void setMessurements(float tem, float humi,float pre){ this.temperature = tem; this.humidity = humi; this.pressure = pre; messureChanged(); } //因为采用的是notifyObservers()方法,所以采用的是拉的方式更新数据,所以需要提供get方法。 public float getTemperature(){ return temperature; } public float getHumidity(){ return humidity; } public float getPressure(){ return pressure; }}
3,观察者实现jdk提供的Observer接口,那么会使用内部封装好的update()方法,所以需要注意类型强转。
package com.liu;import java.util.Observable;import java.util.Observer;public class CurrentConditionsDisplay implements Observer, DisplayElement { private Observable observable; private float temperature; private float humidity; public CurrentConditionsDisplay(Observable observable) { // TODO Auto-generated constructor stub this.observable = observable; observable.addObserver(this); } @Override public void display() { // TODO Auto-generated method stub System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "%humidity"); } @Override public void update(Observable o, Object arg) { // TODO Auto-generated method stub if(o instanceof WeatherData){ WeatherData weatherData = (WeatherData)o; this.temperature = weatherData.getTemperature(); this.humidity = weatherData.getHumidity(); display(); } }}
4,代码结果测试
public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMessurements(12, 12, 12); }}
五,JDK中提到的还有一个notifyObserver(Object obj)的方法可以通知观察者
1,创建一个Datas类
package com.liu;public class Datas {private float temperature;private float humidity;private float pressure; public Datas() { // TODO Auto-generated constructor stub } public float getTemperature() { return temperature; } public void setTemperature(float temperature) { this.temperature = temperature; } public float getHumidity() { return humidity; } public void setHumidity(float humidity) { this.humidity = humidity; } public float getPressure() { return pressure; } public void setPressure(float pressure) { this.pressure = pressure; }}
2,被观察者需要改为:
import java.util.Observable;public class WeatherData extends Observable { private float temperature; private float humidity; private float pressure; private Datas data = new Datas(); public void messureChanged(){ setChanged(); notifyObservers(data); } public void setMessurements(float tem, float humi,float pre){ data.setTemperature(tem); data.setHumidity(humi); data.setPressure(pre); messureChanged(); }}
3,观察者:
package com.liu;import java.util.Observable;import java.util.Observer;public class CurrentConditionsDisplay implements Observer, DisplayElement { private Observable observable; private float temperature; private float humidity; public CurrentConditionsDisplay(Observable observable) { // TODO Auto-generated constructor stub this.observable = observable; observable.addObserver(this); } @Override public void display() { // TODO Auto-generated method stub System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "%humidity"); } @Override public void update(Observable o, Object obj) { // TODO Auto-generated method stub if(o instanceof WeatherData){ WeatherData weatherData = (WeatherData)o; Datas data = (Datas)obj; this.temperature = data.getTemperature(); this.humidity = data.getHumidity(); display(); } }}
4,测试代码不变
public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMessurements(14, 12, 12); }}
0 0
- 观察者模式(OBSERVER)
- 观察者(Observer)模式
- 观察者(Observer)模式
- 观察者(Observer)模式
- 观察者(Observer)模式
- 观察者模式(Observer)
- 观察者模式(Observer)
- Observer(观察者)模式
- 观察者模式(Observer)
- Observer(观察者模式)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者(Observer)模式
- 观察者模式(Observer)
- 观察者模式(Observer)
- 【BZOJ 2154】【JZOJ 1938】【2011集训队出题】Crash的数字表格
- android CoordinatorLayout使用
- ViewConfiguration.get(context).getScaledTouchSlop()的意义
- Python多进程生成多线程
- 微信公众帐号开发教程第4篇-消息及消息处理工具的封装
- 观察者(Observer)模式
- sublime 创建lua项目
- 让你的网页引入思源字体
- linux之PHY
- 持久化消息队列memcacheq的安装配置
- SolrCloud(Win--单机多服务器)
- Android优化浅谈之Java代码优化
- 10期6月份期刊
- js学习笔记2