流利的接口 (最初由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

流利的接口不利于维护相关推荐

  1. xml不利于调试_流利的接口不利于维护

    xml不利于调试 流畅的界面 (最初由Martin Fowler 创造)是一种与OOP中的对象进行通信的非常便捷的方式. 它使他们的外墙更易于使用和理解. 但是,它破坏了它们的内部设计,使它们更难以维 ...

  2. 读《实战 GUI 产品的自动化测试》之:第二步,构建利于维护的自动化测试系统...

    转载自:http://www.ibm.com/developerworks/cn/rational/r-cn-guiautotesting2/ 基石--IBM 框架简介 Rational Functi ...

  3. 我对软件设计原则的理解

    1. 开闭原则 软件实体(class,模块,功能或业务,微服务etc)对修改关闭,对拓展开放. 抽象构建框架,实现拓展细节. 面向抽象编程,而不是面向具体实现编程.因为抽象相对来说是稳定的,让类去依赖 ...

  4. zookeeper的“江湖之路”

    时事前沿:FaceBook放弃zookeeper,转而使用自主研发的配置管理系统,位置感知分发 系统(Location-AwareDistribution,LAD),满足其部署其数百万台的服务器的需求 ...

  5. 实现HTTP协议Get、Post和文件上传功能——使用WinHttp接口实现

    在<使用WinHttp接口实现HTTP协议Get.Post和文件上传功能>一文中,我已经比较详细地讲解了如何使用WinHttp接口实现各种协议.在最近的代码梳理中,我觉得Post和文件上传 ...

  6. 移动端接口:版本的兼容

    来自鼎*的面试问题,简单地说,我搞砸了...我还真的没有考虑过这个问题,稀里糊涂一顿胡说,我都感觉自己丢人. 现在大部分公司都做APP,所以面临一个版本兼容的问题. APP功能的增加导致server接 ...

  7. collection集合 多少钱_Java 集合(2)-- Iterator接口源码超级详细解析

    一.iterator接口介绍 iterator接口,也是集合大家庭中的一员.和其他的Map和Collection接口不同,iterator 主要是为了方便遍历集合中的所有元素,用于迭代访问集合中的元素 ...

  8. Typescript前端接口联调自动化的探究与实践

    源宝导读:Web应用程序一般都是前后端分离的基本架构,而前后端很可能分别是两拨人分别开发,前后端的接口连调成为高频沟通的对象,开发内耗最大的也在这个环节.本文将分享如何基于OpenAPI将前后端接口协 ...

  9. Golang笔记—封装/继承/接口

    基本介绍 Golang 仍然有面向对象编程的继承,封装和多态的特性,只是实现的方式和其它 OOP 语言不一 样,下面我们一一为同学们进行详细的讲解 Golang 的三大特性是如何实现的. 封装介绍 封 ...

最新文章

  1. (002) java后台开发之对象初始化
  2. php滑动换视频,php工具类之【视频变换类】
  3. 数据段、代码段、堆栈段、BSS段的区别
  4. vue 组件 props配置
  5. django model filter_Django开发常用方法及面试题
  6. Docker镜像重命名
  7. 7.26 1004度度熊的午饭时光 百度之星题解
  8. UniFi AP 5.5.20的基本使用与设置(普通漫游和无缝漫游)
  9. EXCEL日期格式不一致设置统一显示格式的方法
  10. android cts测试(编译源码获取cts测试包),如何通过Android CTS测试—testPackageSignatures...
  11. 切换无线网卡失败服务器提示,无线网卡切换为AP模式时提示ICS启动失败的解决方法...
  12. SSDT inlineHook
  13. 最新安卓官方api文档完整版
  14. Python实验报告 实验16 - Python计算生态
  15. logit模型应用实例_最大似然估计(上)——离散选择模型之十
  16. Office使用的窍门和小提示
  17. “CIO生存法则”培训——企业信息主管如何成功的“潜规则”
  18. 有关网络安全方面的书籍(凯文·米特尼克作品)
  19. Waydroid安装问题(依赖: python3-gbinder 但是它将不会被安装)
  20. 【For my liz】宇宙制作全纪录(如果能成功的话TT)

热门文章

  1. UVA10601 Cubes - 波利亚定理
  2. Spring Boot 热部署入门
  3. Java 0xffffffff隐式类型转换的坑
  4. 一文搞定 Spring Data Redis 详解及实战
  5. Vue 阻止事件冒泡
  6. Spring Enable*高级应用及原理
  7. Java NIO总结
  8. java的jdbc驱动server_win7下java用jdbc驱动来连接sql server的方法 (转载)
  9. nginx解析php失败,为什么nginx不能解析php?
  10. ReviewForJob(3)表、栈和队列