Loading

触发链模式之使用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);
    }
}

测试结果:

 

posted @ 2020-08-11 17:40  揸火箭  阅读(253)  评论(0编辑  收藏  举报

Loading