zoukankan      html  css  js  c++  java
  • 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本身就给我们实现了

    这些接口

  • 相关阅读:
    每日英语:Apple's Latest iPhone Puts Focus Back on Fingerprint Security
    每日英语:Stressed at Work? Reflect on the Positive
    每日英语:Hold On: Reasons For Never Giving Up Your Dream
    每日英语:China's New Anti-Graft Website: A Tale of Tigers, Flies and Bath Tubs
    每日英语:China Overtakes U.S. in Number of Diabetes Cases
    每日英语:New Reason To Get The Kids To Bed On Time
    每日英语:Why Are Items Pricier in China?
    每日英语:Burning Question / Does Reading In Dim Light Hurt Your Eyes?
    每日英语:Genetic Manipulation Extends Life of Mice 20%
    架构设计之Spring-Session分布式集群会话管理
  • 原文地址:https://www.cnblogs.com/wscit/p/6229594.html
Copyright © 2011-2022 走看看