设计模式——观察者模式
来源:互联网 发布:h3c stp 阻塞端口 编辑:程序博客网 时间:2024/06/14 18:29
观察者模式确定了对象之间一对多的联系,当某一个对象发生改变时,依赖(观察)他的所有对象会收到通知并更新。
我们通常将被观察的对象称之为主题
观察主题的对象称之为观察者
主题对象:它是数据的拥有者,一个主题对象可以拥有许多个观察者对象,他维护了一个观察者对象的列表,能够在程序运行的时候动态的添加、删除和通知观察者对象。
观察者对象:每个观察者对象在初始化的时候要向指定主题对象为构造函数的参数,并且调用主题对象的添加观察者方法进行注册(也就是将自己添加到主题的观察者列表中)
一般来讲,我们先抽象出一个主题对象接口Observable和一个观察者对象接口Observer。这样做的好处是,在进行工作的时候,由于主题维护的是一组观察者接口,所以并不用了解具体的接口对象是什么,从而实现了松耦合。也符合我们的面向对象编程原则:针对接口编程而不是具体实现。
首先我们来看主题接口Observable,它具有维护观察者列表的基本操作(添加和删除),同时当主题对象发生变化时能够通知所有的观察者
interface Observable{ void registerObserver(Observer observer); void removeObserver(Observer obsrver); void notifyObservers();}
由于在接口中声明的字段都是静态的,所以我们要将观察者对象列表字段放在主题接口的具体实现类中,比如:
class WeatherData implements Subject{ private ArrayList observers; //后面还有必须实现的方法 . . .}
观察者对象也都要实现一个接口Observer,对于所有的观察者对象来说,主题发生改变时都需要向他们(观察者)发送通知,而观察者对象都应该有一个用来更新的操作让主题来调用以便发送数据,所以观察者接口定义了一个Update操作:
interface Observer{ void update(Observable subject,Object args);}
好了介绍到这里,观察者模式的工作原理基本清楚了:主题发生变化,调用函数通知所有的观察者,观察者通过更新函数获得主题数据进行更行
下面是一个完整的例子,主题是一个天气数据,观察者是许多的布告板(布告板上面显示主题中的数据),每当天气数据发生变化时,都要通知布告板要更新啦。
import java.util.ArrayList;public class ObserverPattern { public static void main(String args[]){ WeatherData weatherdata=new WeatherData(); CurrentConditionsDisplay ccd=new CurrentConditionsDisplay(weatherdata); StatisticsDisplay sd=new StatisticsDisplay(weatherdata); weatherdata.setMeasurements(80, 65, 30.4f); weatherdata.setMeasurements(82, 70, 35.4f); weatherdata.setMeasurements(78, 90, 31.4f); }}interface Display{ void display();}interface Observer{ void update(float temperature,float humidaity,float pressure);}interface Subject{ void registerObserver(Observer observer); void removeObserver(Observer obsrver); void notifyObserver();}class WeatherData implements Subject{ private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers=new ArrayList(); } public void registerObserver(Observer o){ observers.add(o); } public void removeObserver(Observer o){ observers.remove(o); } public void measurementsChanged(){ notifyObserver(); } public void notifyObserver(){ for(Object o : observers){ Observer e=(Observer) o; e.update(temperature,humidity,pressure); } } public void setMeasurements(float temperature,float humidity,float pressure){ this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); System.out.println(); }}//布告板一class CurrentConditionsDisplay implements Observer,Display{ private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData){ this.weatherData=weatherData; weatherData.registerObserver(this); } public void update(float temperature,float humidity,float pressure){ this.temperature=temperature; this.humidity=humidity; display(); } public void display(){ System.out.println("Current conditions:"+temperature+"F degress and" +humidity+"%humidity"); }}//布告板二class StatisticsDisplay implements Display,Observer{ private float higherTemperature=-100; private float lowerTemperature=100; private float averageTemperature=0; int count=0; private Subject subject; public StatisticsDisplay(Subject s){ this.subject=s; s.registerObserver(this); } public void update(float temperature,float humidity,float pressure){ if(temperature>this.higherTemperature) this.higherTemperature=temperature; if(temperature<this.lowerTemperature) this.lowerTemperature=temperature; averageTemperature=(averageTemperature*count+temperature)/(++count); display(); } public void display(){ System.out.println("HigerTemperature:"+this.higherTemperature+"F LowerTemperature:"+this.lowerTemperature+"F AverageTemperature:"+this.averageTemperature); }}
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者模式
- 设计模式—观察者
- 设计模式——观察者设计模式
- 设计模式——观察者
- 设计模式——观察者
- 设计模式 —— 观察者
- 设计模式——观察者
- 【设计模式】——观察者
- 设计模式——观察者模式
- 每日设计模式——观察者模式
- “完全背包”详解及实现(包含背包具体物品的求解)
- 九度 oj 1125
- Machine Learning “for Dummies” (part 2)
- Bug模式之写入的数据格式出错
- js内置对象(Math对象)
- 设计模式——观察者模式
- hdu 5396 区间DP
- linux基础操作--设置系统时间
- Android,去掉页面标题栏
- 既见君子 云胡不喜
- 部分真题整理3
- 根据前序序列和中序序列,重建一颗树(PHP递归实现)
- SDWebImage使用详解及流程分析
- 九度OJ 题目1083:特殊乘法