通俗的说:我们向报社订阅报纸,这个就是观察者模式的实例,我们是观察者(Observer),报社就是主题(Subject)。
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
现在我们设计一个气象监测站系统,此系统中的三个部分分别是气象站(获取实际气象数据)、布告板(显示当前的天气状况)
、WeatherData(跟踪来自气象站的数据,并更新布告板),布告板可以提供扩展。
系统设计类图如下:
/** * 主题 * @author wengn * */ public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObserver(); } /** * 观察者 * @author wengn * */ public interface Observer { public void update(float temp,float humidity,float pressure); } /** * 布告板接口 * @author wengn * */ public interface DisplayElement { public void display(); } /** * 主题实现类 * @author Administrator * */ public class WeatherData implements Subject { private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers = new ArrayList(); } public void notifyObserver() { for(int i=0;i<observers.size();i++){ Observer o = (Observer)observers.get(i); o.update(temperature, humidity, pressure); } } public void registerObserver(Observer o) { observers.add(o); } public void removeObserver(Observer o) { int i = observers.indexOf(o); if(i>=0){ observers.remove(i); } } public void measurementsChanged(){ this.notifyObserver(); } public void setMeasurements(float temperature,float humidity,float pressure){ this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } } /** * 布告板实现类 * @author wengn * */ public class CurrentConditionsDisplay implements Observer, DisplayElement { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject s){ this.weatherData = s; weatherData.registerObserver(this); } public void update(float temp, float humidity, float pressure) { this.temperature = temp; this.humidity = humidity; display(); } public void display() { System.out.println("show:"+temperature+"||"+humidity); } } /** * 测试类 * @author wengn * */ public class Test { public static void main(String[] args) { WeatherData wd = new WeatherData(); CurrentConditionsDisplay ccd = new CurrentConditionsDisplay(wd); wd.setMeasurements(0, 0, 0); wd.setMeasurements(1, 1, 1); wd.setMeasurements(2, 2, 2); } }
附上java awt中观察者模式的模拟代码:
package com.hanbing.awt; import java.util.ArrayList; import java.util.List; public class MyAwt { public static void main(String[] args) { Button bt = new Button(); MyActionLisenter lisenter = new MyActionLisenter(); MyActionLisenter2 lisenter2 = new MyActionLisenter2(); bt.addActionLisenter(lisenter); bt.addActionLisenter(lisenter2); bt.buttonPressed(); } } class Button { private List<ActionLisenter> list = new ArrayList<ActionLisenter>(); public void buttonPressed() { ActionEvent e = new ActionEvent(System.currentTimeMillis(), this); for (ActionLisenter lisenter:list) { lisenter.actionPerformed(e); } } public void addActionLisenter(ActionLisenter lisenter) { list.add(lisenter); } } interface ActionLisenter { public void actionPerformed(ActionEvent e); } class MyActionLisenter implements ActionLisenter { public void actionPerformed(ActionEvent e) { System.out.println("oh my god!!!"); } } class MyActionLisenter2 implements ActionLisenter { public void actionPerformed(ActionEvent e) { System.out.println("oh my god2!!!"); } } class ActionEvent { private long when; private Object source; public ActionEvent(long when, Object source) { super(); this.when = when; this.source = source; } public long getWhen() { return when; } public Object getSource(){ return source; } }