首先看看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);
}
}

测试结果:

触发链模式之使用jdk的Observable和Observerver实现触发链模式(附JDK源码)的更多相关文章

  1. 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 百篇博客分析OpenHarmony源码 | v36.04

    百篇博客系列篇.本篇为: v36.xx 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CP ...

  2. 给jdk写注释系列之jdk1.6容器(10)-Stack&Vector源码解析

    前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈.      什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶 ...

  3. 自动化测试po模式是什么?自动化测试po分层如何实现?-附详细源码

    一.什么是PO模式 全称:page object model  简称:POM/PO PO模式最核心的思想是分层,实现松耦合!实现脚本重复使用,实现脚本易维护性! ​ 主要分三层: 1.基础层BaseP ...

  4. PHP伪造referer突破网盘禁止外链(附115源码)

    新建一个文件file.php.后面的参数就是需要伪造referfer的目标地址吧.如:file.php/http://www.xxx.xxx/xxx.mp3 复制内容到剪贴板 代码: <?$ur ...

  5. [区块链\理解BTCD源码]GO语言实现一个区块链原型

    摘要 本文构建了一个使用工作量证明机制(POW)的类BTC的区块链.将区块链持久化到一个Bolt数据库中,然后会提供一个简单的命令行接口,用来完成一些与区块链的交互操作.这篇文章目的是希望帮助大家理解 ...

  6. eclipse无法断点调试JDK源码的问题

    最近换了新版的eclipse,在jdk源码里面,打断点发现无法进入源码调试,程序直接跳过,已查资料发现自己eclipse配置的是jre环境的. 此处要配成jdk目录才有效 打开preferences, ...

  7. 曹工力荐:调试 jdk 中 rt.jar 包部分的源码(可自由增加注释,修改代码并debug)

    背景 大家知道,jdk安装的目录下,一般会有个src.zip包,这个包基本对应了rt.jar这个包.rt.jar这个包里面,就放了jdk中,jdk采用java实现的那部分类库代码,比如java.lan ...

  8. Mybatis源码手记-从缓存体系看责任链派发模式与循环依赖企业级实践

    一.缓存总览 Mybatis在设计上处处都有用到的缓存,而且Mybatis的缓存体系设计上遵循单一职责.开闭原则.高度解耦.及其精巧,充分的将缓存分层,其独到之处可以套用到很多类似的业务上.这里将主要 ...

  9. 设计模式(十八)——观察者模式(JDK Observable源码分析)

    1 天气预报项目需求,具体要求如下: 1) 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方). 2) 需要设计开放型 API,便于其他第三方也能接入气象 ...

随机推荐

  1. C++代码规约--命名约定

    目录 通用命名规则 文件命名 类型命名 变量命名 常量命名 函数命名 宏命名 枚举命名 命名空间命名 命名规则的特例 学习自Google C++编程规约 通用命名规则 函数命名, 变量命名, 文件命名 ...

  2. 小白从零开始阿里云部署react项目+node服务接口(二:node服务+web)

    我们用极简的方式来创建服务,没有任何附加功能 1 新建一个server文件夹 2 使用npm init 或者yarn init  一路enter 3  yarn add  express cors  ...

  3. JAVA 实现将多目录多层级文件打成ZIP包后保留层级目录下载 ZIP压缩 下载

    将文件夹保留目录打包为 ZIP 压缩包并下载 上周做了一个需求,要求将数据库保存的 html 界面取出后将服务器下的css和js文件一起打包压缩为ZIP文件,返回给前台:在数据库中保存的是html标签 ...

  4. 题解 洛谷 P3340 【[ZJOI2014]星系调查】

    根据题意,发现题目中的图,其实就是一颗树或者是一颗基环树,每个节点上有一个点对\((x,y)\),每次询问为给定端点,找一条直线到端点间的所有点的距离之和最小. 设这条直线为\(y=kx+b\),根据 ...

  5. 题解 洛谷 P2046 【[NOI2010]海拔】

    首先进行贪心,发现海拔有梯度时一定是不优的,最优的情况是海拔像断崖一样上升,也就是左上角有一片海拔高度为\(0\),右下角有一片海拔高度为\(1\). 发现这样的性质后,不难想到用最小割来解决问题,但 ...

  6. SUCTF2019-web Easyweb

    <?php function get_the_flag(){ // webadmin will remove your upload file every 20 min!!!! $userdir ...

  7. 使用faker生成测试数据

    需要先安装faker模块,pip install faker 导入模块中的Faker类:from faker import Faker 实例化faker = Faker() print('姓名相关') ...

  8. 第三章 Java面向对象(下)

    3.1.抽象类 概述:在做子类共性功能抽取时,有些方法在父类中并没有具体的体现,这个时候就需要抽象类了 格式:public abstract class 类名 {} 语法特点: 抽象类和抽象方法必须使 ...

  9. 将"089,0760,009"变为 89,760,9

    remove_zeros = lambda s: ','.join(map(lambda sub: str(int(sub)), s.split(','))) remove_zeros("0 ...

  10. 将BX中的数以二进制形式在屏幕上显示出来。

    问题 将BX中的数以二进制形式在屏幕上显示出来. 代码 code segment assume cs:code main proc far start: mov bx,011001100110b ;假 ...