流利的接口不利于维护

流利的接口 (最初由Martin Fowler 创造)是一种非常方便的与OOP中的对象进行通信的方式。 它使他们的外墙更易于使用和理解。 但是,它破坏了它们的内部设计,使它们更难以维护。 Marco Pivetta在他的博客文章Fluent Interfaces is Evil中说了几句话; 现在我加几分钱。

唐尼·布拉斯科(1997)

让我们看一下我自己的库jcabi-http ,它是几年前创建的,当时我认为流畅的接口是一件好事。 这是您使用库发出HTTP请求并验证其输出的方式:

String html = new JdkRequest("https://www.google.com").method("GET").fetch().as(RestResponse.class).assertStatus(200).body();

这种便捷的方法链接使代码简短明了,对吧? 是的,表面上确实如此。 但是,包括JdkRequest在内的库类的内部设计远非优雅。 最大的问题是它们很大,而且


无法扩展它们而不扩大它们。

例如,现在JdkRequest具有方法method()fetch()和其他一些方法。 需要新功能时会发生什么? 添加它的唯一方法是通过添加新方法来扩大类的范围,这是我们危害其可维护性的方式。 例如, 在这里 ,我们添加了multipartBody() , 在这里我们添加了timeout() 。

在jcabi-http中收到新功能请求时,我总是感到害怕。 我了解这很可能意味着向RequestResponse和其他已经膨胀的接口和类添加新方法。

我实际上试图在库中做一些事情来解决这个问题,但这并不容易。 查看此.as(RestResponse.class)方法调用。 它所做的是用RestResponse装饰一个Response ,以便使其方法更丰富。 我只是不想让Response包含50多种方法,就像许多其他库一样。 这是它的作用(这是伪代码):

class Response {RestResponse as() {return new RestResponse(this);}// Seven methods
}
class RestResponse implements Response {private final Response origin;// Original seven methods from Response// Additional 14 methods
}

如您所见,我没有将所有可能的方法添加到Response ,而是将它们放置在补充修饰符RestResponseJsonResponseXmlResponse 等中 。 它有帮助,但是要使用Response类型的中心对象编写这些装饰器,我们必须使用“ ugly”方法as() ,该方法as()很大程度上依赖于Reflection和类型转换 。

流利的接口意味着大型类或某些丑陋的解决方法。

换句话说,流畅的界面意味着大型类或一些丑陋的解决方法。 当我写有关Streams API和接口Stream的文章时 ,我曾提到过这个问题,它非常流畅。 有43种方法!

这是流畅接口的最大问题-它们迫使对象变得巨大。

流利的接口非常适合其用户,因为所有方法都在一个地方,并且类的数量非常少。 使用它们很容易,尤其是在大多数IDE中使用代码自动完成功能时。 它们也使客户端代码更具可读性,因为“流利的”结构看起来类似于纯英语(aka DSL )。

没错! 但是,它们对对象设计造成的损害是价格过高。

有什么选择?

我建议您改为使用装饰器和智能对象 。 如果现在可以做的话,这就是我设计jcabi-http的方法:

String html = new BodyOfResponse(new ResponseAssertStatus(new RequestWithMethod(new JdkRequest("https://www.google.com"),"GET"),200)
).toString();

这与上面的第一个代码段中的代码相同,但是它更加面向对象。 当然,此代码的明显问题是IDE无法自动完成几乎所有操作。 同样,我们将不得不记住许多类的名称。 对于那些习惯了流利界面的人来说,该结构看起来很难阅读。 此外,它与DSL的想法相距甚远。

流畅的界面对用户有利,但对开发人员不利。 小对象对开发人员有好处,但难以使用。

但是,这里是好处列表。 首先,每个对象都很小,非常有凝聚力,并且它们都是松散耦合的,这在OOP中是显而易见的优点。 其次,向库中添加新功能就像创建新类一样容易。 无需接触现有课程。 第三,由于类很小,因此简化了单元测试。 第四,所有类都是不可变的,这在OOP中也很明显 。

因此,有用性和可维护性之间似乎存在冲突。 流利的接口对用户有利,但对库开发人员则不利。 小对象对开发人员有好处,但难以理解和使用。

似乎是这样,但前提是您已经习惯于大型类和过程编程。 对我来说,大量的小班学习似乎是一种优势 ,而不是缺点。 即使我不确定确切的类最适合我,内部清晰,简单且易读的库也更易于使用。 即使没有代码自动完成功能,我也可以自己解决,因为代码很干净。

另外,我经常发现自己对在代码库内部或通过对库的拉取请求扩展现有功能感兴趣。 如果我知道所引入的更改是孤立的并且易于测试,那么我对此更感兴趣 。

因此,我再也没有流畅的界面,只有对象和装饰器。

翻译自: https://www.javacodegeeks.com/2018/03/fluent-interfaces-are-bad-for-maintainability.html

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

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

相关文章

减小程序规模!稀疏数组Sparsearray,数据结构二维数组与稀疏数组转换,Java实现

文章目录基本介绍应用实例基本介绍 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。 稀疏数组的处理方法是: ①记录数组一共有几行几列,有多少个不同的值(0除外)。 ②把具有不同值…

C语言课程设计报告输出杨辉三角,C语言学习:在屏幕上输出杨辉三角

杨辉三角的规律是:它的两条斜边都是由数字1组成的,而其余的数则是等于它肩上的两个数之和。 代码如下:#include#includeint main(){int i,j,k,arr[10][10]{0};/*arr[11][11]必须初始化,初始化为{0}*/printf("打印出杨辉三角&…

习惯性朴实简单!一起学习MySQL常见单行函数,字符数学日期流程控制

文章目录一、字符函数二、数学函数三、日期函数四、其他函数五、流程控制函数一、字符函数 1、大小写控制函数 ①UPPER():转换成大写 SELECT UPPER(Hello);②LOWER():转换成小写 SELECT LOWER(Hello);2、字符控制函数 ①LENGTH():获取参数…

不可上位!数据结构队列,老实排队,Java实现数组模拟队列及可复用环形队列

文章目录队列简介数组模拟队列(无法复用)数组模拟环形队列(可复用)队列简介 队列是一个有序列表,可以用数组或是链表来实现。 遵循先入先出的原则。即先存入队列的数据,先取出,后存入的后取出…

多对一!分组查询!MySQL分组函数,聚合函数,分组查询

文章目录一、简单使用二、搭配DISTINCT去重三、COUNT()详细介绍四、分组查询一、简单使用 SUM:求和(一般用于处理数值型) AVG:平均(一般用于处理数值型) MAX:最大(也可以用于处理字…

数据结构单链表SingleLinkedList,Java实现单链表增删改查

文章目录链表介绍应用示例链表介绍 链表是有序的列表,但是它在内存中是存储是不连续的,如下: 链表是以节点的方式来存储,是链式存储: ①每个节点包含data域存储数据,next域指向下一个节点 ②链表的各个节点…

c语言队列原理的实现,c印记(十二):队列queue原理与实现

一、简而言之在百度百科里面摘取了一段关于队列(queue)的介绍:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。…

w ndows7与XP哪个好,Win7系统与Win XP系统哪个更好?Windows7与WindowsXP区别介绍-系统城·电脑系统下载之家...

虽然微软已经停止对xp系统的维护,但是仍有不少用户有这样一个疑惑:Win7系统与WinXP系统哪个更好?接下来,小编就向大家具体介绍Windows7与WindowsXP的区别,让你知道到底哪个系统会更好一些。首先跟系统城小编一起来看微…

一文完整MySQL连接查询,笛卡尔乘积,内连接外连接交叉连接

文章目录笛卡尔乘积连接查询分类等值连接非等值连接自连接外连接交叉连接连接查询又称为多表查询,当查询的字段来自于多个表时,使用连接查询。 笛卡尔乘积 笛卡尔乘积现象:表1有m行,表2有n行,结果有m*n行 发生原因&a…

【PostmanJMeter】使用Postman和JMeter进行signature签名

一、前言 ​ 有些接口的请求会带上sign(签名)进行请求,各接口对sign的签名内容、方式可能不一样,但一般都是从接口的入参中选择部分内容组成一个字符串,然后再进行签名操作, 将结果赋值给sign; 完整规范的接口文档都会…

詹金斯搭建_詹金斯的Maven报告

詹金斯搭建代码质量是一个敏感的话题。 它会影响您的维护成本以及客户满意度。 更不用说您的开发人员使用代码的动力了。 谁想要修复难看的代码,对吗? 讨论代码质量总是需要事实和数字! 因此,这是一个简短的教程,介绍…

Oracle应用容器云的自由

在这篇博客文章中,我将介绍如何部署CloudEE封装在杜克大学应用自由尤伯杯罐子Oracle应用集装箱云端 。 在Oracle Application Container Cloud中进行部署所需的部署工件是一个ZIP归档文件,其中包含应用程序ber-jar和清单文件(manifest.json&…

简洁明了!Java实现单向环形链表以解决约瑟夫环Josepfu问题

文章目录简单介绍代码实现简单介绍 如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点。 单向环形链表应用场景:Josephu(约瑟夫、约瑟夫环)问题&#xf…

荣耀v10Android9新功能,荣耀10、荣耀V10开启安卓9.0内测 日常领跑行业

【PConline 资讯】今天(8月9日)早上10点,荣耀总裁赵明发微博宣布荣耀已经有四款机型面向少部分用户推送安卓9.0内部测试版本。实际上,在8月8日晚上,花粉论坛就已经公布华为4款机型内测安卓 9.0 版本,荣耀手机两款旗舰进入升级名单…

状态模式 设计模式_设计模式:状态

状态模式 设计模式本文将介绍状态设计模式 。 它是行为设计模式之一 。 您无需了解许多理论即可了解模式的主要概念。 该文章将分为几个部分,在其中我将提供有关需要应用该模式的情况,它所具有的利弊以及用法示例的信息。 有时,当对象的内部…

Java中的AES加密和解密(CBC模式)

通过有线方式传输诸如纯文本密码之类的机密数据总是容易受到安全性的影响,始终建议对此类信息进行加密并使用SSL传输这些机密数据.Java为此提供了多种加密算法。在本文中,我们将讨论Java中具有CBC模式的AES(高级加密标准)对称加密…

hiti打印机android驱动,HiTi 打印机 驱动程序下载——更新 HiTi 软件

HiTi 打印机驱动程序下载如何手动下载和更新:你可以通过 %%os%% 或通过执行 Windows 更新获取基本的 HiTi Printer 驱动程序。 内置驱动程序将支持Printer的基本功能,但通常不支持更高级的功能。以下是手动更新这些 HiTi 设备驱动程序的完整指南。程序员: HiTi 类别…

Java实现最小二乘法线性拟合,传感与检测,单臂半桥全桥实验,江南大学自动化

因为作为资源上传不方便我们获取且我想免费分享给有需要的小伙伴,以后所有实验报告都通过文章形式记录输出了,仅供参考,欢迎交流。(最小二乘法代码在文末) 电桥特性曲线: Java实现最小二乘法线性拟合及计算…

android task详解,Android AsyncTask的使用详解

当然,我们在进行耗时操作或者更新UI时,是可以使用匿名线程的,但是此种方式是存在缺陷的:第一,线程的开销较大,如果每个任务都要创建一个线程,那么应用 程序的效率要低很多;第二&…

【Error】IDEA报错:org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType cannot be cast t

错误日志: org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType cannot be cast to org.jetbrains.jps.builders.java.dependencyView.TypeRepr$ClassType 解决方法: