Java观察者模式定义对象间一对多的依赖关系,当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都得到通知并自动更新。JDK中提供的观察者模式的实现是由java.util.Observer接口和java.util.Observable类组成的,其中Observer代表观察者,而Observable代表被观察者。
1、Observable类是由被观察者(可有一个或多个观察者)所继承,调用setChanged方法,是的hasChanged方法返回值为true,则再次调用notifyObservers方法会触发观察者的update方法来通知观察者该实例发生变化。
2、Observer接口中只有一个为实现的update抽象方法,实现该接口的对象称为观察者,该对象要实现update方法。注册了该对象(观察者)的对象(被观察者)实例在调用notifyObservers方法之后,会自动调用观察者中的update方法。
3、被观察者I114gBoxHeaterObservable.java,代表热水器,继承Obserable,其实现如下:
/** * */ package com.i114gbox.sdk.designMode.observer; import java.util.Observable; /** * 热水器--被观察者 * * @author shenjichao@vivagame.cn * */ public class I114gBoxHeaterObservable extends Observable { // 水温 private int temperature; public int getTemperature() { return temperature; } public void setTemperature(int temperature) { this.temperature = temperature; } // 烧水 public void boilWater() { for (int i = 10; i <= 100;) {// 初始水温为15度 temperature = i; // 调用setChanged(),hasChanged()将返回true this.setChanged(); // 当hasChanged()返回true时,监听被观察者的观察者将调用update() this.notifyObservers(); i += 10; } } }
4、在扮演观察者角色的同时,又扮演被观察者的角色,类名为I114gBoxDisplayObservable.java,代表显示器,继承Observable类,实现Observer接口,其实现如下:
/** * */ package com.i114gbox.sdk.designMode.observer; import java.util.Observable; import java.util.Observer; import java.util.logging.Logger; /** * 显示器--观察者(用于观察热水器),被观察者(被报警器观察) * * @author shenjichao@vivagame.cn * */ public class I114gBoxDisplayObservable extends Observable implements Observer { private static Logger logger = Logger .getLogger(I114gBoxDisplayObservable.class.getSimpleName()); private String status = I114gBoxWaterStatus.COLD.toString(); public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } // 显示水温 private void displayTemperature(int temperature) { // 当水被烧开时 if (temperature == 100) { this.setStatus(I114gBoxWaterStatus.HOT.toString()); this.setChanged(); this.notifyObservers(temperature); } logger.info("水状态为:" + status + "|" + "现在水温为:" + temperature); } // 当被观察者状态发生改变时,调用该方法 @Override public void update(Observable observable, Object data) { this.displayTemperature(((I114gBoxHeaterObservable) observable) .getTemperature()); } }
5、观察者I114gBoxAlarmObserver.java,代表报警器,实现Observer接口,其实现如下:
/** * */ package com.i114gbox.sdk.designMode.observer; import java.util.Observable; import java.util.Observer; import java.util.logging.Logger; /** * 报警器--观察者 * * @author shenjichao@vivagame.cn * */ public class I114gBoxAlarmObserver implements Observer { private static Logger logger = Logger.getLogger(I114gBoxAlarmObserver.class .getSimpleName()); // 当水烧开了调用该方法 @Override public void update(Observable observable, Object data) { this.makeAlarm((Integer) data); } // 报警 private void makeAlarm(int temperature) { logger.info("滴滴滴……水烧开了!"); } }
6、观察者模式测试类Test.java,其实现如下:
/** * */ package com.i114gbox.sdk.designMode.observer; /** * 观察者模式测试类 * * @author shenjichao@vivagame.cn * */ public class Test { public static void main(String[] args) { I114gBoxHeaterObservable heater = new I114gBoxHeaterObservable(); I114gBoxDisplayObservable display = new I114gBoxDisplayObservable(); I114gBoxAlarmObserver alarm = new I114gBoxAlarmObserver(); // 加入观察者 // 显示器用来观察热水器 heater.addObserver(display); // 报警器用来观察显示器 display.addObserver(alarm); // 烧水 heater.boilWater(); } }
7、运行测试类,结果如下:
8、注意事项
优点:
支持松耦合和减少依赖性;
观察者数目可变
缺点:
性能降低;
内存泄露;
测试调试困难