Java设计模式(观察者模式JDK自带)

来源:互联网 发布:spss19.0软件 编辑:程序博客网 时间:2024/05/29 15:18
JDK自带的观察者模式和我们上一节说的基本相似,也有通用的观察协议规则 Observer,这个接口中只有一个方法,就是update方法
public interface Observer {    void update(Observable o, Object arg);}

JDK也有一个可观察者 Observable类,如下
public class Observable {    private boolean changed = false;    private Vector<Observer> obs;    public Observable() {        obs = new Vector<>();    }    public synchronized void addObserver(Observer o) {        if (o == null)            throw new NullPointerException();        if (!obs.contains(o)) {            obs.addElement(o);        }    }    public synchronized void deleteObserver(Observer o) {        obs.removeElement(o);    }    public void notifyObservers() {        notifyObservers(null);    }    public void notifyObservers(Object arg) {               Object[] arrLocal;        synchronized (this) {                       if (!changed)                return;            arrLocal = obs.toArray();            clearChanged();        }        for (int i = arrLocal.length-1; i>=0; i--)            ((Observer)arrLocal[i]).update(this, arg);    }    public synchronized void deleteObservers() {        obs.removeAllElements();    }    protected synchronized void setChanged() {        changed = true;    }    protected synchronized void clearChanged() {        changed = false;    }    public synchronized boolean hasChanged() {        return changed;    }    public synchronized int countObservers() {        return obs.size();    }}

和我们写的有一点差异,jdk里面有个changed变量,而且每次通知时候都会去检测changed,只有当changed为true是才会去通知
这个说明了jdk在通知之前必须设置changed为true,才能进行通知,可是为什么要用这个呢,很多人都不明白,那就跟我一起来看看吧!其实这样设置是有好处的,让你在用观察者时更有弹性,你可以更适当的通知观察者。比方说,我们又一个温度监测站,当温度变化时,我们需要更新显示板上的显示,可是检测温度的硬件设备是非常灵敏的,但是我们的更新不需要做到那么的敏感,而且也不需要更新的那么频繁,所以我们就要在特定的条件下才能对温度的显示进行更新,这个就发挥出jdk中的setChanged的用处了,可以在特定的条件下去改变changed,这样温度通知才能发出,通知到每个注册者

接下来我们重新实现我们观察模式的实例,用jdk自带的类进行
由于要设置changed,而set方法是protected类型的,所以我们要重新封装这个类,并且要继承jdk自带的:

观察者:
public class BossSubject extends Observable {public void registerObserver(Observer observer) {addObserver(observer);}public void removeObserver(Observer observer) {removeObserver(observer);System.out.println("成功告诉观察者我不需要被通知了");}public void setChanged() {super.setChanged();}public void notifyAllObserver() {System.out.println("开始通知");notifyObservers();System.out.println("所有的都已通知!");}}

展示接口:
public interface DisplayWork {//收到通知后,打印一下自己正在干什么void display();}


注册对象必须实现jdk自带的OBserver接口,并在update里面进行相应的响应事件操作

public class Worker implements Observer, DisplayWork {private String name;private String des;public Worker(String name, String des) {super();this.name = name;this.des = des;}@Overridepublic void display() {System.out.println("我在" + des + "了!");}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void update(Observable o, Object arg) {System.out.println("老板来了," + name + "好好干活啦!");this.display();}}

基本的东西都写好了,我们写个测试类测试一下吧
public class Test {public static void main(String[] args) {//首先定义一个观察者去观察BossSubject sub = new BossSubject();//定义张三,写代码Worker zs = new Worker("张三", "写代码");//告诉观察者,我需要知道老板什么时候来的sub.registerObserver(zs);//定义李四,管后勤Worker ls = new Worker("李四", "管后勤");//告诉观察者,我需要知道老板什么时候来的sub.registerObserver(ls);//定义王五,写代码Worker ww = new Worker("王五", "秘书");//告诉观察者,我需要知道老板什么时候来的sub.registerObserver(ww);//这时候,老板来了,告诉所有的人,老板来了//这个没有设置changedSystem.out.println("jdk changed not config");sub.notifyObservers();System.out.println("jdk changed config");sub.setChanged();sub.notifyAllObserver();}}

这个测试类我们分别能看到我们在没有设置changed和设置changed是的结果
jdk changed not configjdk changed config开始通知老板来了,王五好好干活啦!我在秘书了!老板来了,李四好好干活啦!我在管后勤了!老板来了,张三好好干活啦!我在写代码了!所有的都已通知!


从结果中可以看出,当我们没有设置changed是进行通知是无效的,这就是jdk自带的观察者模式和我们自己写的观察者的区别之处了,jdk的观察者还是比较好,程序的弹性比较好。

好了,这节就说到这里了,请继续关注我们后续的设计模式讲解。

END

1 0
原创粉丝点击