触发链模式之使用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);
- }
- }
测试结果:
触发链模式之使用jdk的Observable和Observerver实现触发链模式(附JDK源码)的更多相关文章
- 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 百篇博客分析OpenHarmony源码 | v36.04
百篇博客系列篇.本篇为: v36.xx 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CP ...
- 给jdk写注释系列之jdk1.6容器(10)-Stack&Vector源码解析
前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶 ...
- 自动化测试po模式是什么?自动化测试po分层如何实现?-附详细源码
一.什么是PO模式 全称:page object model 简称:POM/PO PO模式最核心的思想是分层,实现松耦合!实现脚本重复使用,实现脚本易维护性! 主要分三层: 1.基础层BaseP ...
- PHP伪造referer突破网盘禁止外链(附115源码)
新建一个文件file.php.后面的参数就是需要伪造referfer的目标地址吧.如:file.php/http://www.xxx.xxx/xxx.mp3 复制内容到剪贴板 代码: <?$ur ...
- [区块链\理解BTCD源码]GO语言实现一个区块链原型
摘要 本文构建了一个使用工作量证明机制(POW)的类BTC的区块链.将区块链持久化到一个Bolt数据库中,然后会提供一个简单的命令行接口,用来完成一些与区块链的交互操作.这篇文章目的是希望帮助大家理解 ...
- eclipse无法断点调试JDK源码的问题
最近换了新版的eclipse,在jdk源码里面,打断点发现无法进入源码调试,程序直接跳过,已查资料发现自己eclipse配置的是jre环境的. 此处要配成jdk目录才有效 打开preferences, ...
- 曹工力荐:调试 jdk 中 rt.jar 包部分的源码(可自由增加注释,修改代码并debug)
背景 大家知道,jdk安装的目录下,一般会有个src.zip包,这个包基本对应了rt.jar这个包.rt.jar这个包里面,就放了jdk中,jdk采用java实现的那部分类库代码,比如java.lan ...
- Mybatis源码手记-从缓存体系看责任链派发模式与循环依赖企业级实践
一.缓存总览 Mybatis在设计上处处都有用到的缓存,而且Mybatis的缓存体系设计上遵循单一职责.开闭原则.高度解耦.及其精巧,充分的将缓存分层,其独到之处可以套用到很多类似的业务上.这里将主要 ...
- 设计模式(十八)——观察者模式(JDK Observable源码分析)
1 天气预报项目需求,具体要求如下: 1) 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方). 2) 需要设计开放型 API,便于其他第三方也能接入气象 ...
随机推荐
- Linux下Storm2.1.0的伪分布式安装
官方下载网址:http://storm.apache.org/downloads.html 1.第一步我们先从官网下载解压包 2.然后进行解压 3.配置环境变量 在profile里面插入如下格式语句 ...
- IDEA 格式化代码快捷键
一般都是:Ctrl+Alt+L 如果未格式化的话,可能与以下软件的快捷键冲突了: QQ 网易云 也可能是其他的快捷键组合,具体可查看工具栏Code->Reformat Code: 也可重新设置i ...
- Intelij DataGrip 的安装和使用
链接: Intelij DataGrip 安装教程以及汉化教程 Intelij DataGrip 使用教程 以上两个教程已使用过,没有问题 如有侵权请联系删除
- TLV通信协议
基础 TLV协议是BER编码的一种,全称是Tag.length.value.该协议简单高效,能适用于各种通信场景,且具有良好的可扩展性.TLV协议的基本格式如下: 其中,Tag占2个字节,是报文的唯一 ...
- Python如何向SQLServer存储二进制图片
需求是需要用python往 SqlServer中的image类型字段中插入二进制图片 核心代码,研究好几个小时的代码: 安装pywin32,adodbapi image_url = "图片链 ...
- php必须掌握的常用函数
数学函数 数组函数 字符串函数
- DJANGO-天天生鲜项目从0到1-002-用户模块-注册
本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...
- git上传本地项目到gitlab
<1>输入git config --global user.name "你的用户名" <2>输入git config --global user.email ...
- goroutine间的同步&协作
Go语言中的同步工具 基础概念 竞态条件(race condition) 一份数据被多个线程共享,可能会产生争用和冲突的情况.这种情况被称为竞态条件,竞态条件会破坏共享数据的一致性,影响一些线程中代码 ...
- 10-Pandas之数据融合(pd.merge()、df.join()、df.combine_first()详解)
一.pd.merge() pd.merge()的常用参数 参数 说明 left 参与合并的左侧DataFrame right 参与合并的右侧DataFrame how 如何合并.值为{'left',' ...