Observer,Observable实现观察者模式
(#)个人对于观察者的理解:观察者与发布订阅模式是非常的相似的,例如当多个威信使用者订阅了同一个主题之后,那么这个主题就是一个被观察者,而这些用户就是观察
者,当这个主题更新了新的内容以后,就要通知所有的观察者,主题更新了新的内容了
(#)TaLK IS CHEEP 场景:服务器解析DNS
1.抽象一个域名解析服务,实现java.util的Observer与Observable
/** * Author: scw * Time: 16-12-28 */ public abstract class DnsServer extends Observable implements Observer{ public void update(Observable o, Object arg) { Recorder recorder = (Recorder) arg; if(isLocal(recorder)){ recorder.setIp(getIPAddress()); sign(recorder); }else{ responseFromUpperServer(recorder); } } /** * 增加观察者 */ public void setUpperServer(DnsServer dnsServer){ super.deleteObservers(); super.addObserver(dnsServer); } /** * 向父dns请求解析,通知观察者 */ private void responseFromUpperServer(Recorder recorder){ super.setChanged(); super.notifyObservers(recorder); } public abstract void sign(Recorder recorder); public abstract boolean isLocal(Recorder recorder); public String getIPAddress(){ return "127.0.1.1"; } }
2.三个具体的域名解析服务
/** * Author: scw * Time: 16-12-28 */ public class SHDnsServer extends DnsServer { @Override public void sign(Recorder recorder) { recorder.setOwner("上海服务器"); } @Override public boolean isLocal(Recorder recorder) { return StringUtils.endsWith(recorder.getDomain(),".sh"); } } /** * Author: scw * Time: 16-12-28 */ public class ChinaDnsServer extends DnsServer { @Override public void sign(Recorder recorder) { recorder.setOwner("中国服务器"); } @Override public boolean isLocal(Recorder recorder) { return StringUtils.endsWith(recorder.getDomain(),".cn"); } } /** * Author: scw * Time: 16-12-28 */ public class TopDnsServer extends DnsServer { @Override public void sign(Recorder recorder) { recorder.setOwner("世界"); } @Override public boolean isLocal(Recorder recorder) { return StringUtils.endsWith(recorder.getDomain(),".www"); } }
3.ok,上面的步奏都实现了的话,那么接下来随便写一个main方法测试一下就好了,这个很easy,那么大家应该很好奇这两个接口都干了什么呢?下面解析一下
(#)接口解析
1.ObServer,其实这个接口很简单,内部只有一个update方法,所以实现的重点不在这里
2.Observable类,看过源码之后,发现这个类是线程安全的,使用了Vector来存储,所有的观察者,同时对于change的设置也是同步的
下面来看一下关键一个notifyObservers方法:
看见了吧,这个方法的关键就是最后一行代码,也就是说一个观察者的类应该去实现这Observer接口,重写里面的update方法,那么在被观察者做出改变的时候就能很
简单的通知到观察者的update方法。
(#)最后这个接口其实很简单,但是其中涉及到的设计模式还是很值得参考的,而且以前写这种模式的时候也一直是自己来实现,从来发现原来java本身就给我们实现了
这些接口