设计模式之观察者(Observer)模式
??????? Observer模式中文名称叫观察者模式,在Java中,可以通过JDK提供的java.util.Observable类和 java.util.Observer接口实现Observer模式。Observer模式定义对象间的一对一或一对多的依赖关系,当一个对象(Observable)的状态发生改变时, 所有依赖于它的对象(Observer)都得到通知并被自动更新。
???
下面,我们分别来看下Observable类和Observer接口的方法和作用。
1、?Observable? 类代表 被观察者 (java.util.Observable )
??????? 主要方法有:
??????? void setChanged() : 设置被观察者的状态已经被改变
??????? void addObserver(Observer? observer) : 添加观察者
??????? int countObservers() : 返回所有观察者的数目
??????? void deleteObserver(Observer? observer) :删除指定观察者
??????? void deleteObservers() : 删除所有观察者
??????? boolean hasChanged() : 被观察者的状态是否被改变,如果是则返回true,否则返回false
??????? void notifyObservers()? : 通知所有观察者(没有参数)
??????? void notifyObservers(Object arg) : 通知所有观察者(带参数,参数一般设定为被改变的属性)
??????? void clearChanged() :清除被观察者状态的改变(即调用 hasChanged() 时会返回 false)
2、Observer 接口代表 观察者 (java.util.Observer )
??????? void update(Observable observable, Object arg) :当 被观察者 调用 notifyObservers(*) 方法
时,会根据被观察者的 hasChanged() 方法 来判断 它的状态是否被改变, 如果被观察者的状态被改变了,则
会调用 观察者 的 update 方法,参数 observable 为 被观察者对象, arg 为调用 notifyObservers( Object arg ) 时传入的参数 arg ,如果调用的是 notifyObservers() 方法, 则 arg 为 null( 注意 :应该把这个参数 arg 设定为 被观察者的 被改变的属性)。
?
以下是一个Observer模式的例子:
1、被观察者Car类,继承至Observable类
package com.huawei.observer.observable;import java.util.Observable;public class Car extends Observable implements Runnable{private Float gasoline;//汽车的汽油量public Car(Float gasoline) {super();this.gasoline = gasoline;}public Float getGasoline() {return gasoline;}public void setGasoline(Float gasoline) {this.gasoline = gasoline;}/** * 模拟汽车行驶过程中的耗油的方法 */public synchronized void consume(){if(--gasoline < 5){//若油箱中的油少于5升则让汽车提示驾驶员加油。this.setChanged();this.notifyObservers(gasoline);//通知驾驶员加油。}}/** * 模拟汽车的行驶过程 */@Overridepublic void run() {while(Boolean.TRUE){consume();if(gasoline == 0){//当油箱中还剩0升油时汽车停止break;}try {Thread.sleep(1000);//每一秒钟耗油1升} catch (InterruptedException e) {e.printStackTrace();}}}}
?
2、观察者Driver类,实现Observer接口
package com.huawei.observer.observer;import java.util.Observable;import java.util.Observer;import com.huawei.observer.observable.Car;public class Driver implements Observer {private String name;//驾驶员名字public Driver(String name) {super();this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void update(Observable observable, Object object) {Car car = null;//当前行驶的汽车。Float gasoline = null;//当前行驶的汽车的油量。if(observable instanceof Car){car = (Car)observable;}else{return ;}if(object instanceof Float){gasoline = (Float)object;}else{return ;}if(gasoline != 0){System.out.println("驾驶员"+name+"您好,您的油箱汽油还剩 " + gasoline + " 升,请尽快加油!" );}else{System.out.println("驾驶员"+name+"您好,您的油箱已无汽油,汽车已停止!" );}}}
?
3、测试类Test
package com.huawei.observer.main;import com.huawei.observer.observable.Car;import com.huawei.observer.observer.Driver;public class Test {/** * @param args */public static void main(String[] args) {Car car = new Car(35F);//实例化被观察者,即汽车,初始状态油箱35升油。Driver driver = new Driver("William");//实例化观察者,即汽车驾驶员,名字是William。car.addObserver(driver);//为被观察者(汽车)添加观察者(驾驶员)new Thread(car).start();//启动汽车行驶的线程,每一秒钟耗油1升。}}
?
?
4、运行测试类,(汽车行驶30秒钟后)输出结果如下:
驾驶员William您好,您的油箱汽油还剩? 4.0 升,请尽快加油!
驾驶员William您好,您的油箱汽油还剩? 3.0 升,请尽快加油!
驾驶员William您好,您的油箱汽油还剩? 2.0 升,请尽快加油!
驾驶员William您好,您的油箱汽油还剩? 1.0 升,请尽快加油!
驾驶员William您好,您的油箱已无汽油,汽车已停止!