hamcrest_重新设计Hamcrest

hamcrest

我在Hamcrest库上做了几篇文章 ,我确实很喜欢使用它,但是我希望对其进行一些更改。 我了解他们所做的大多数设计决策,但我认为其中一些确实不值得。

介绍Litecrest

我对库所做的大多数更改都有助于减轻Hamcrest的负担,因为我觉得有些事情不必要地减轻了负担。 这就是为什么我将更改称为Litecrest。 它不会是一个实际的库; 这只是大声思考。 我也希望您能从中学到一些有关设计库的知识。

没有说明

Description接口以及StringDescriptionBaseDescription类实际上并不值得。 他们提供了列表转换为字符串好看一些不错的方法,但toString()在所有这些方法应该是足够的。 如果不是这样,可以将一些protected final方法放在BaseMatcher ,以方便地为列表构建字符串。 当然,这并没有真正遵循SRP密切,所以你可以使用类似 Description ,以提供方便的方法。

说明,否则不是很有帮助。 它的存在性假设它专门用于提供从长远来看可能不是String的输出。 作为一个使用良好的库,将其从String更改为与输出无关的类型会破坏向后兼容,但这种更改不太可能需要。 应用YAGNI , Description类就在厕所下面。

无输出参数

所述describeTo()describeMismatch 不宜服用在Description或附加物体的任何其它类型的字符串,尤其是作为out参数(某物,以避免尽可能经常)。 既然这些方法没有开始的返回类型,那么绝对没有理由使用out参数。

仔细研究问题,您将发现根本没有理由使用参数。 我了解到,他们可能一直在试图迫使匹配器的创建者不使用String串联,但事实并非如此。 如果匹配器的描述只是一个简单的小字符串,则没有理由他们不应该仅仅返回该字符串。 就个人而言,我将删除Description参数,并为它们提供String或CharSequence的返回类型。 我考虑使用CharSequence因为那样会给使用StringBuilder带来更大的动力,但是简单地返回String也不是什么大问题,因为他们可以在其上调用toString() 。 不过,我也可能会使用CharSequence ,因为我将在断言逻辑中使用StringBuilder来将输出放在一起,并且StringBuilder也可以接受CharSequence ,因此唯一的toString()必须在完成输出时被调用。

类型安全

Matcher接口采用通用参数,该参数与matches()方法一起使用,但是所述方法采用Object而不是通用类型。 javadoc声称这是由于类型擦除引起的,但我不认为这是一个问题。 我没有做任何挖掘来尝试是否可以将其切换为通用类型,但是如果我发现您实际上可以使用通用类型,则可以。 这消除了对TypeSafeMatcher的需要,因为它也检查null,因此可以用更简单的NullCheckingMatcher代替,或者仅实现它,以便断言在捕获到NullPointerException将不匹配描述更改为“为null”。 通过执行所有这些操作,我们可以消除所有其他双倍的基类,这些基类必须加倍以覆盖类型安全匹配器和不那么重要的匹配器。 (例如: CustomMatcherCustomTypeSafeMatcherDiagnosingMatcherTypeSafeDiagnosingMatcher ,以及我加倍的ChainableMatcher ,摆脱了两个DiagnosingMatcher的影响;它们的设计很差,两次调用matches()

更改一些名字

我真的不喜欢describeTo()这个名字。 应该是describeExpected()describeMatch() 。 我了解他们遵循JMock ConstraintsSelfDescribing的命名约定,但是看到他们没有费心完成其余方法签名的复制,实际上并没有任何SelfDescribing

CustomMatcher S的关系被称为OneOffMatcher S或QuickMatcher秒。 Custom是一个令人误解的名称,听起来您需要对其进行扩展才能创建自己的匹配器。

文档中的更多示例

我不确定该库中有几类有用,因为它们的文档未显示其用法。 Condition就是其中之一。 从少量的文档看来,这似乎是相对有用的,但是由于它没有提供使用示例(并且它是一个具有内部接口和两个内部类的相对复杂的文件),我不知道如何使用它。 它还没有记录其公共方法,因此我不确定它们是否需要大量研究。

FeatureMatcher已有不错的文档,但是同样,没有示例。

那些为图书馆编写文档的人在任何时候都牢记这一点; 如果不是很明显(通常,即使不是很明显),则应给出使用中的类的示例。

删除无关的类

其中一些已经被直接或间接地解决了。 删除Description及其所有子类。 删除SelfDescribing ,因为它仅在Description仍然存在时才真正有用。 删除所有TypeSafe版本的基本匹配器。 卸下Diagnosing匹配器。 我不确定是否应该删除Condition因为我没有太大用。 如果保留Condition ,那么最终在核心org.hamcrest包中有五个原始的十一个类,在api org.hamcrest包中有四个原始的两个接口。

现在,让我们深入研究org.hamcrest.internal包。 ArrayIterator没什么用,因为您只能使用可以与foreach循环一起使用的数组。 NullSafety似乎模仿Arrays.toList()功能,但是用IsNull匹配器替换了null匹配器。 我看不到这有什么帮助,因此将其删除。 ReflectiveTypeFinder可能最终会有用。 我只看到它在TypeSafeMatcherFeatureMatcher ,尽管我不确定在FeatureMatcher使用了多少。 不过,我会保留。 最后两个处理的是SelfDescribing ,我们已将其删除,因此这两个处理也是一样。 这仅使ReflectiveTypeFinder脱离了以前的五个类。

我不打算讨论所有其他匹配器。 在大多数情况下,已添加它们的用途。 由于删除了这么多的基类,几乎所有的类都可能必须进行更改。

Lambdas!

如果将新的功能范例也应用到hamcrest,则可以扩展匹配器概念的实用性。 我没有想太多,但是对于一次性匹配器,您可以修改库以包括一个新的assertThat()方法,如下所示:

public static  void assertThat(T item, String description, Predicate matcher) {if(!matcher.test(item)) {StringBuilder output = new StringBuilder();output.append("Expected: ").append(description).append("\n      but: was").append(item.toString());throw new AssertionError(output.toString());}
}

这将使您可以编写类似于以下内容的断言:

assertThat("cats", "doesn't contain \"dogs\"", str -> !str.contains("dogs"));

实际上,实际上我已经在ez-testing迷你库中添加了LambdaAssert类,因此您可以将其与原始的hamcrest库一起使用。

匹配器接口

实际上有一个Matcher接口是毫无意义的,因为hamcrest希望您扩展BaseMatcher而不是实现Matcher 。 如果您非常不想让任何人实现,那么为什么要创建一个接口? 特别是因为BaseMatcher为我们所做的唯一事情就是为describeMismatch()创建一个默认实现describeMismatch()并“实现”放置在此处的不赞成使用的方法,告诉您使用BaseMatcher而不是Matcher )。

如果您真的不希望人们使用该界面,请摆脱它。 就我个人而言,由于无论如何我总是会重写describeMismatch() ,因此我认为只实现接口就完全可以了,而不必让JVM加载实际上为我提供任何东西的基类。

另外,由于我们现在有了Java 8,所以该接口可以只使用默认方法来实现默认实现。 我知道可以避免这种情况,因为较旧的Java版本将无法利用这一点。

所以,要么只是BaseMatcher或没事的Matcher正在实施。

奥托罗

我还想更改其他一些小事情,例如,迫使人们重写describeMismatch()而不是提供默认值,但是我甚至不确定那个,因为默认值通常足够有效。 无论如何,即使您有一个受欢迎的图书馆,也并不意味着它是完美的。 始终注意进行重构。

不幸的是,所有这些更改都不是向后兼容的,但有时是值得的。

翻译自: https://www.javacodegeeks.com/2015/01/redesigning-hamcrest.html

hamcrest

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

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

相关文章

程序员鄙视链python_关于程序员之间的鄙视链

鄙视像条食物链,是个绕不开的怪圈。在这个怪圈中,每一个人,都在链条的最末端。朋友圈有鄙视链,相亲有鄙视链,程序员圈也有鄙视链看完下面的鄙视链,你是那一层?↓↓↓↓【1】努力成为全栈&#x…

java自定义jsp标签_自定义JSP标签

1 写一个标签处理类//标签处理类public class IpTag implements SimpleTag {private PageContext pageContext;//Web容器调用NO1public void setJspContext(JspContext pc) {System.out.println("setJspContext()");pageContext (PageContext) pc;}//Web容器调用NO2…

新手学习C语言编程的8个致命错误,你中招了吗?

序言C语言的最大特点是:功能强、使用方便灵活。C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下“灵活的余地”。但由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不…

java与java ee_Java EE拦截器

java与java ee历史 我认为重要的是要看一下Java EE中Interceptor的发展,因为它是从EJB特定的项目开始的,后来又演变成一个单独的规范,现在可供其他Java EE规范扩展,这一事实很简单。 版本1.0 拦截器最初是在EJB 3.0 (…

python怎么查询元素是否在列表中_python怎么判断某一元素是否在列表中

定义一个列表,并判断元素是否在列表中。python学习网,大量的免费python基础教程,欢迎在线学习!例如:test_list [ 1, 6, 3, 5, 3, 4 ]print("查看 4 是否在列表中 ( 使用循环 ) : ")for i in test_list:if(i…

python中带附件发送电子邮件_python发送带附件邮件

Python SMTP发送邮件SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。Python创建 SMTP 对象…

jpa 实体图查询_JPA实体图

jpa 实体图查询JPA 2.1的最新功能之一是可以使用实体图指定获取计划。 这很有用,因为它允许您自定义使用查询或查找操作检索的数据。 在使用中大型应用程序时,通常以不同的方式显示来自同一实体的数据。 在其他情况下,您只想选择最小的信息集…

C语言程序控制语句——while

while语句while (表达式) 语句当表达式为非0值(真)时,执行while循环体中的语句,如此往复,直到表达式的值等于0(假),循环结束。如以下示例程序,循环…

kettle 资料_Kettle的使用-初级

本文从kettle的简介、下载、安装、初级使用来展开。1.kettle是什么?kettle是一款开源的ETL工具。可以运行在Windows和linux上。2.下载地址https://community.hitachivantara.com/s/article/downloads3.安装因为Kettle是基于Java开发的,所以要先安装jdk环…

python抢货程序_写个Python程序上下班抢个顺风单

#!/usr/bin/python# -*- coding: gb2312 -*-##########################################################################2015-12-11 09:47:46#author: 358275018qq.com#使用Python2.6/7######################################################################### 有些库没…

C语言 | 语句概述

C语言语句的作用和分类1、9种控制语句if()...else.. //条件语句 for()... //循环语句 while()... //循环语句 do...while() //循环语句 continue //结束本次循环语句 break //中止执…

react性能优化方案_React灵敏且性能卓越的Spray + Akka解决方案,以“在Java和Node.js中发挥并发性和性能”...

react性能优化方案在我以前的文章中,我研究了一个虚拟的交易引擎,并将基于Java的阻止解决方案与基于Node.js的非阻止解决方案进行了比较。 在文章的结尾,我写道: 我怀疑随着Node.js的最近成功,越来越多的异步Java库将…

linux 查看日志_干货 | 名企高频考点之谈谈Linux日志查看方式都有哪些

点击蓝字关注我哦以下是本期干货视频视频后还附有文字版本哦▼《名企高频考点-谈谈Linux日志查看方式都有哪些》▼ps:请在WiFi环境下打开,如果有钱任性请随意0.概述在我们面试各大公司的时候,关于Linux往往最容易问到的问题之一就是Linux指令…

vsm java_java – 我尝试使用JAXB将对象编组到xml文件中时,错误为“缺少@XmlRootElement注释”...

我是刚刚开始使用JAXB的人,所有我需要的是将对象写入xml并在某些时候将其读回java这是我的班级:public class VSM implements java.io.Externalizable{ArrayList termList; //Term DictionaryArrayList queryTermList; //Query listArrayList> docLists;ArrayLis…

jvm7 jvm8_自我修复的JVM

jvm7 jvm8这篇帖子是关于一个应用程序的示例,其中解决每个IT问题的第一个解决方案-“您是否尝试过将其关闭并重新打开”-可能适得其反,弊大于利。 我们不需要关闭电源,而是拥有可以自愈的应用程序:它在一开始就失败了&#xff0c…

实例讲解C语言的位运算

C语言位运算有6种&#xff1a; &&#xff0c; | , ^(异或)&#xff0c; <<(左移)&#xff0c;>>(右移)。注意&#xff1a;参与位运算的元素必须是int型或者char型&#xff0c;以补码形式出现。1.按位与&&运算常应用于&#xff1a;迅速清零保留指定位判…

python3解释器执行not 1 and 1_编程语言的分类,python解释器多版本共存.执行python的两种方式,变量,用户与程序交互...

一、编程语言的分类&#xff1f;机器语言&#xff1a;直接使用二进制指令编程&#xff0c;直接操作硬件&#xff0c;必须考虑硬件细节。汇编语言&#xff1a;用简写的英文标识符取代二进制去编写程序&#xff0c;直接操作硬件&#xff0c;必须考虑硬件细节。高级语言&#xff1…

java字节码执行原理_《Java 底层原理》Java 字节码详解

前言我们在开发中会遇到一些Java的执行超出我们的想象&#xff0c;但是又不知道他为什么会这样执行&#xff0c;这个时候我们就需要能够知道他编译后Class文件是什么样子的&#xff0c;并且理解字节码的含义。Java字节码的原理进制class文件就是字节码文件&#xff0c;直接是打…

C语言学习笔记--位运算

这一节主要说的是位运算&#xff0c;计算机中的执行速度&#xff1a;位运算 > 加减 > 乘除 > 求余位运算就是将数字转换成二进制后进行运算&#xff0c;之后再将数字转换成原来的进制与运算&#xff1a;当两个数相与时&#xff0c;只有都为l的时候结果才为1&#xff0…

openshift学习_在OpenShift上将JMS与JBoss A-MQ结合使用。 学习了有关远程客户端和加密的经验。...

openshift学习OpenShift是“红帽开发的开放式混合云应用程序平台”。 它具有不同的风格&#xff0c;对于大多数您想做的事情&#xff0c;最有趣的部分是公共云应用程序开发和托管平台“ OpenShift Online ”。 您可以轻松地尝试一下&#xff0c;因为在云中使用OpenShift Online…