【源码】hamcrest 源码阅读 空对象模式、模板方法模式的应用

文章目录

    • 前言
    • 1. 类图概览
    • 2. 源码阅读
      • 2.1 抽象类 BaseMatcher
      • 2.1 接口 Description
        • 提炼模式:空对象模式
      • 2. 接口 Description 与 SelfDescribing 配合使用
        • 提炼模式 模板方法
    • 后记

前言

hamcrest ,一个被多个测试框架依赖的包。听说 hamcrest 的源码质量很高,特此来学习一下。建议fork原仓库,拉到本地看代码。

  • 代码仓库
    hamcrest github 仓库

1. 类图概览

  • 看个大概的类图。很经典的接口、抽象类、子类实现
    在这里插入图片描述

2. 源码阅读

将源码逐一拆解,提取有借鉴意义的编码方式。

2.1 抽象类 BaseMatcher

基类提供了基础方法。
在这里插入图片描述

  • 一个很有趣的方法名
    在接口层面告诉使用者不要直接实现 Matcher 接口,而是继承 BaseMatcher
	@Deprecatedvoid _dont_implement_Matcher___instead_extend_BaseMatcher_();

2.1 接口 Description

BaseMatcher 中的方法依赖 Description 接口。

	@Overridepublic void describeMismatch(Object item, Description description) {}@Overridepublic String toString() {return StringDescription.toString(this);}

看看这个接口有什么特殊的地方。

提炼模式:空对象模式
  • Description 接口使用静态内部类包装一个 “空对象”,表达 “什么也不做”
public interface Description {/*** A description that consumes input but does nothing.*/static final Description NONE = new NullDescription();
}

在这里插入图片描述

  • BaseMatcher 主要使用的 StringDescription
    在这里插入图片描述

可以用idea的查找依赖功能,能看到 “空实现” 使用的地方

在这里插入图片描述

2. 接口 Description 与 SelfDescribing 配合使用

  • 一个有意思的写法
 	@Overridepublic String toString() {return StringDescription.toString(this);}
  • 发现 Matcher 父接口 SelfDescribing 的使用痕迹,用于表达 Matcher 自身的信息 (由开发者决定)
public interface Matcher<T> extends SelfDescribing {}
  • 接口定义
public interface SelfDescribing {void describeTo(Description description);
}
提炼模式 模板方法
  • 声明一个自己的matcher 方法调用链如下 (省掉了与该模式无关的方法和类)
    在这里插入图片描述
  • BaseMatcher 中的模板方法就是 toString()
    @Overridepublic String toString() {return StringDescription.toString(this);}
  • 子类需要自定义describe逻辑 (模板方法toString会回调这个方法 )
	@Overridepublic void describeTo(Description description) {// EG: BigDecimalCloseTo 的声明description.appendText("a numeric value within ").appendValue(delta).appendText(" of ").appendValue(value);}

后记

笔者认为,如果存在大量的抽象类实现类,hamcrest 空对象模式可以借鉴一下。
hamcrest 的 toString 模板方法把 describe 逻辑很好的解耦到子类了,下次遇到需要追加上下文的实现可以参考这个模式(如上文的BigDecimalCloseTo )。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/150778.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 DMA从存储器发送数据到串口

1.任务描述 &#xff08;1&#xff09;ds18b20测量环境温度存储到存储器&#xff08;数组&#xff09;中。 &#xff08;2&#xff09;开启DMA将数组中的内容&#xff0c;通过DMA发送到串口 存在问题&#xff0c;ds18b20读到的数据是正常的&#xff0c;但是串口只是发送其低…

机器学习7:pytorch的逻辑回归

一、说明 逻辑回归模型是处理分类问题的最常见机器学习模型之一。二项式逻辑回归只是逻辑回归模型的一种类型。它指的是两个变量的分类&#xff0c;其中概率用于确定二元结果&#xff0c;因此“二项式”中的“bi”。结果为真或假 — 0 或 1。 二项式逻辑回归的一个例子是预测人…

Scala第十七章节

Scala第十七章节 scala总目录 文档资料下载 章节目标 了解集合的相关概念掌握Traversable集合的用法掌握随机学生序列案例 1. 集合 1.1 概述 但凡了解过编程的人都知道程序 算法 数据结构这句话, 它是由著名的瑞士计算机科学家尼古拉斯沃斯提出来的, 而他也是1984年图灵…

车险计算器微信小程序源码 带流量主功能

车险计算器微信小程序源码带流量主功能&#xff0c;可以精准的算出车险的书目&#xff0c;是一个非常实用的微信小程序源码。 简单的计算让你得知车险价值 另外也支持流量主&#xff0c;具体小编也就不多说了&#xff0c;大家自己搭建研究吧。 源码下载&#xff1a;https://d…

React xlsx(工具库) 处理表头合并

前端导出excel表格 引入xlsx插件&#xff0c;不然应该是运行不起来的 npm i xlsx xlsx中文文档 插件2 exceljs npm i exceljs exceljs中文文档 导出 例子 import { ExportExcel } from ./exportExcel/index;const columns[{title: id,dataIndex: item1,},{title: 序号,dataInd…

开环模块化多电平换流器仿真(MMC)N=6(Simulink仿真)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

RabbitMQ之Fanout(扇形) Exchange解读

目录 基本介绍 适用场景 springboot代码演示 演示架构 工程概述 RabbitConfig配置类&#xff1a;创建队列及交换机并进行绑定 MessageService业务类&#xff1a;发送消息及接收消息 主启动类RabbitMq01Application&#xff1a;实现ApplicationRunner接口 基本介绍 Fa…

12.1 使用键盘鼠标监控钩子

本节将介绍如何使用Windows API中的SetWindowsHookEx和RegisterHotKey函数来实现键盘鼠标的监控。这些函数可以用来设置全局钩子&#xff0c;通过对特定热键挂钩实现监控的效果&#xff0c;两者的区别在于SetWindowsHookEx函数可以对所有线程进行监控&#xff0c;包括其他进程中…

Spring Cloud Gateway2之路由详解

Spring Cloud Gateway路由 文章目录 1. 前言2. Gateway路由的基本概念3. 三种路由1. 静态路由2. 动态路由1. 利用外部存储2. API动态路由 3. 服务发现路由(自动路由)3.1. 配置方式3.2 自动路由&#xff08;服务发现&#xff09;原理核心源码GatewayDiscoveryClientAutoConfigur…

机器学习算法基础--KNN分类算法

文章目录 1.KNN算法原理介绍2.KNN分类决策原则3.KNN度量距离介绍3.1.闵可夫斯基距离3.2.曼哈顿距离3.3.欧式距离 4.KNN分类算法实现5.KNN分类算法效果6.参考文章与致谢 1.KNN算法原理介绍 KNN&#xff08;K-Nearest Neighbor&#xff09;工作原理&#xff1a; 在一个存在标签的…

Springcloud支付模块

客户端消费者80 order&#xff08;订单模块&#xff09; 微服务提供者8001 payment&#xff08;支付模块&#xff09; 订单模块可以调动支付模块 步骤&#xff1a; 1、建moudle 2、改写pom 3、写yml 4、主启类 5、业务类 1、建父工程&#xff08;创建spri…

架构师选择题--计算机网络

架构师选择题--计算机网络 22年考题21年考题20年考题19年真题2017考题 22年考题 d http:80 https:httpssl &#xff1a;443 b b pop3是邮件接收协议&#xff1a;110 SMTP是邮件发送协议&#xff1a;25 http:80 A 网络隔离&#xff1a;防火墙&#xff08;逻辑&#xff09;&…

C++(反向迭代器)

前言&#xff1a; 上一章我们介绍了适配器&#xff0c;也提了一下迭代器适配器&#xff0c;今天我们就从反向迭代器把迭代器适配器给解释一下。 既然 都叫迭代器容器了 就说名只要接口合适他可以封装实现各种容器需求包括vector list 。 目录 1.反向迭代器设计 1.1反向迭代…

Spring面试题学习: 单例Bean是单例模式吗?

单例Bean是单例模式吗 学习背景答案扩展知识单例模式Spring BeanJava Bean单例Bean 个人评价我的回答 学习背景 想换工作. 学习记录, 算是一个输出. 答案 通常来说, 单例模式是指在一个JVM中, 一个类只能构造出一个对象. 有很多方法来实现单例模式, 比如饿汉模式. 但是我们通…

【JVM】 类加载机制、类加载器、双亲委派模型详解

文章目录 前言一、类加载机制二、类加载器三、双亲委派模型总结 前言 &#x1f4d5;各位读者好, 我是小陈, 这是我的个人主页 &#x1f4d7;小陈还在持续努力学习编程, 努力通过博客输出所学知识 &#x1f4d8;如果本篇对你有帮助, 烦请点赞关注支持一波, 感激不尽 &#x1f4d…

配置文件生成器-秒杀SSM的xml整合

配置文件生成器-秒杀SSM的xml整合 思路&#xff1a; 通过简单的配置&#xff0c;直接生成对应配置文件。 maven坐标 <dependencies><!-- 配置文件生成 --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker<…

Java中栈实现怎么选?Stack、Deque、ArrayDeque、LinkedList(含常用Api积累)

目录 Java中的Stack类 不用Stack有以下两点原因 1、从性能上来说应该使用Deque代替Stack。 2、Stack从Vector继承是个历史遗留问题&#xff0c;JDK官方已建议优先使用Deque的实现类来代替Stack。 该用ArrayDeque还是LinkedList&#xff1f; ArrayDeque与LinkList区别&#xff1…

mysql MVCC(多版本并发控制)理解

最近看MVCC相关资料&#xff0c;这边做一个记录总结&#xff0c;方便后续理解。 目录 一、MVCC相关概念 二、MVCC实现原理 1.隐藏字段 2.undo log 3.Read View 4.MVCC的整体处理流程 5. RC&#xff0c;RR级级别下的innoDB快照读有什么不同 6.总结 一、MVCC相关概念 1…

Mysql——创建数据库,对表的创建及字段定义、数据录入、字段增加及删除、重命名表。

一.创建数据库 create database db_classics default charsetutf8mb4;//创建数据库 use db_classics;//使用该数据库二.对表的创建及字段定义 create table if not exists t_hero ( id int primary key auto_increment, Name varchar(100) not null unique, Nickname varchar(1…

机器视觉工程师,公司设置奖金,真的为了奖励你吗?其实和你没关系

​据说某家大厂&#xff0c;超额罚款&#xff0c;有奖有罚很正常&#xff0c;但是我觉得你罚款代理商员工就不一样了&#xff0c;把代理商当成你的员工&#xff0c;我就觉得这些大厂的脑回路有问题。 有人从来没听说过项目奖金&#xff0c;更没有奖金。那么为什么设置奖金呢&a…