设计模式——观察者众( 二 )


设计模式——观察者众

文章插图
【设计模式——观察者众】官方生态
对于观察者模式的用武之地,博主反复查询了一下,似乎在Java的GUI工具包Swing中才有比较多的应用,不过业界似乎对Java的图形化界面开发不太感冒,博主也无力讲解 。但是对于观察者模式的实现,JDK中是早就有现成的一套API——分别是java.util.接口【观察者】和java.util. 类【主题】,有兴趣的可以简单了解:
public interface Observer {//主题对象发生改变,该方法被调用void update(Observable o, Object arg);}
public class Observable {//标记对象状态,状态为true表示对象改变,才会通知观察对象private boolean changed = false;//观察者对象容器private Vector 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();}/***标记对象状态为 true 已改变*注意这是 protected 方法,也就是说,你只有继承该类才能执行状态改变,否则无法应用该类提供的通知模式 */protected synchronized void setChanged() {changed = true;}/*** 标记对象不再改变*/protected synchronized void clearChanged() {changed = false;}public synchronized boolean hasChanged() {return changed;}/*** @return 返回观察者数目*/public synchronized int countObservers() {return obs.size();}}
这里只简单的带大家分析了下源码,如有可能,你或可以学得一些设计技巧,除此之外,就没必要深究了,因为JDK自己的这套观察者模式的 API 并不推荐大家使用,似乎也没见人用过 。一方面,其作为JDK1.0 就出现的元老级API是有些过时,其存放观察者的容器是同样不推荐使用的,另一方面也是最重要的一点就是其主题对象被设计成了一个类而不是接口,基于Java单继承的原则,你的类认了该类为父,那扩展性就会大打折扣 。探访源码博主还发现一个细节,就是 和一出生就很孤独,竟然在JDK内部都没有两者的任何扩展(继承或实现)或引用,可见其虽为亲生,但是多么的不受待见 。当然,API虽然不推荐大家使用,但是仅就源码的写法或者技巧来说,还是有值得学习的方面,怎么说呢,去其糟粕,取其精华吧!
场景运用
设计模式只是将待解的问题抽象化而已,真正的运用难点是还原到实际场景本身,要结合实际场景进行灵活变化,但思想不离其宗 。
这里博主举一个线程回调的例子 。我们知道,Java中线程启动后的执行的 run 方法是没有返回值的,为了获取线程任务执行的结果,通常的做法就是回调(PS:当然可以用的方式来获取异步执行结果,这也是一种方式),在 run 方法执行完毕的时候执行回调方法将子线程的执行结果返回 。如果有多个地方需要子线程的执行结果,就可以采用观察者模式来进行操作 。先定义主题和观察者接口:
//主题抽象public interface Subject {void registerObserver(ICallback callback);void removeObserver(ICallback callback);void notifyObserver();}//观察者抽象 根据业务需要自己定义观察者动作public interface ICallback {void update(String result);}