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

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;
	}


	@Override
	public void display() {
		System.out.println("我在" + des + "了!");
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	@Override
	public 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);
		
		//这时候,老板来了,告诉所有的人,老板来了
		//这个没有设置changed
		System.out.println("jdk changed not config");
		sub.notifyObservers();
		System.out.println("jdk changed config");
		sub.setChanged();
		sub.notifyAllObserver();
	}
}

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


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

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

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值