触发链模式之使用jdk的Observable和Observerver实现触发链模式(附JDK源码)
首先看看JDK的Observer接口
public interface Observer { void update(Observable o, Object arg); }
也就一个更新的方法,这里是要写自己要处理事情的逻辑(代码干活的地方)
然后就是Observable类,因为方法过多不好阅读,所以直接看大纲
方法大概就是设置改变状态,设置观察者,通知观察者等等....
我这里就说明下通知观察者的方法
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); }
简单点也就是去调用Observer接口的Update方法
弄懂这些就可以实现一个触发链模式了,代码如下(DNS解析的一个简单的实现)
执行图:
UML示例图:
观察者抽象:
package zen.design.pattern.creat.观察者模式.DNS解析; import java.util.Observable; import java.util.Observer; import java.util.Random; /** * <p>既是观察者也是被观察者</p> * * @作者 five-five * @创建时间 2020/8/11 */ public abstract class DnsServer extends Observable implements Observer { //处理请求,也就是接收到事件后的处理 @Override public void update(Observable o, Object arg) { Recorder recorder = (Recorder) arg; if (isLocal(recorder)) { recorder.setIp(generateIpAddress()); } else { responsFromUpperServer(recorder); } sign(recorder); } private String generateIpAddress() { Random random = new Random(); return random.nextInt(255) + "." + random.nextInt(255) + "." + random.nextInt(255) + "." + "." + random.nextInt(255); } void setUpper(DnsServer dnsServer) { super.deleteObservers(); super.addObserver(dnsServer); } private void responsFromUpperServer(Recorder recorder) { super.setChanged(); super.notifyObservers(recorder); } abstract void sign(Recorder recorder); protected abstract boolean isLocal(Recorder recorder); }
观察者实现类:
package zen.design.pattern.creat.观察者模式.DNS解析; /** * @作者 five-five * @创建时间 2020/8/11 */ public class ChinaTopDnserver extends DnsServer { @Override void sign(Recorder recorder) { recorder.setOwner("中国"); } @Override protected boolean isLocal(Recorder recorder) { return recorder.getDomain().endsWith(".cn"); } }
package zen.design.pattern.creat.观察者模式.DNS解析; /** * @作者 five-five * @创建时间 2020/8/11 */ public class SHDnserver extends DnsServer { @Override void sign(Recorder recorder) { recorder.setOwner("上海"); } @Override protected boolean isLocal(Recorder recorder) { return recorder.getDomain().endsWith(".sh"); } }
package zen.design.pattern.creat.观察者模式.DNS解析; /** * @作者 five-five * @创建时间 2020/8/11 */ public class TopDnserver extends DnsServer { @Override void sign(Recorder recorder) { recorder.setOwner("全球"); } @Override protected boolean isLocal(Recorder recorder) { return true; } }
然后就是操作的实体类
package zen.design.pattern.creat.观察者模式.DNS解析; /** * @作者 five-five * @创建时间 2020/8/11 */ public class Recorder { //持有者 private String owner; //域名 private String domain; //IP地址 private String ip; public Recorder() { } public void setDomain(String domain) { this.domain = domain; } public void setIp(String ip) { this.ip = ip; } public void setOwner(String owner) { this.owner = owner; } public String getOwner() { return owner; } public String getDomain() { return domain; } public String getIp() { return ip; } @Override public String toString() { return "Recorder{" + "owner='" + owner + '\'' + ", domain='" + domain + '\'' + ", ip='" + ip + '\'' + '}'; } public Recorder(String domain, String ip) { this.domain = domain; this.ip = ip; } }
测试代码:
package zen.design.pattern.creat.观察者模式.DNS解析; /** * @作者 five-five * @创建时间 2020/8/11 */ public class Client { public static void main(String[] args) { DnsServer shdns = new SHDnserver(); DnsServer cndns = new ChinaTopDnserver(); DnsServer topdns = new TopDnserver(); cndns.setUpper(topdns); shdns.setUpper(cndns); Recorder recorder = new Recorder(); recorder.setDomain(".cf"); shdns.update(null,recorder); System.out.println(recorder); } }
测试结果: