实用程序类(也称为帮助程序类)是仅具有静态方法且不封装任何状态的“结构”。 StringUtilsIOUtilsFileUtils从Apache的共享 ; Guava的 IterablesIterators以及JDK7的Files是实用程序类的完美示例。

这种设计思想在Java世界(以及C#,Ruby等)中非常流行,因为实用程序类提供了在各处使用的通用功能。

在这里,我们要遵循DRY原则并避免重复。 因此,我们将通用代码块放入实用程序类中,并在必要时重新使用它们:

// This is a terrible design, don't reuse
public class NumberUtils {public static int max(int a, int b) {return a > b ? a : b;}
}

确实,这是一种非常方便的技术!

实用程序类是邪恶的

但是,在面向对象的世界中,实用程序类被认为是非常不好的实践(有些甚至可能说“可怕”)。

关于这个主题已经有很多讨论。 仅举几例: Helper Classs Evil? 作者:尼克·马利克(Nick Malik),西蒙·哈特(Simon Hart)指出, 帮手,单身人士和实用程序类为什么大多数情况下是不好的,韦德元帅避免使用实用程序类 , 杀死 实用程序类 ! 由Dhaval Dalal撰写, 帮助类是 Rob Bagby的代码气味 。

此外,在StackExchange上还有一些关于实用程序类的问题: 如果“实用程序”类是邪恶的,那么我应该将通用代码放在哪里? , 实用程序类是邪恶的 。

他们所有论点的简要总结是,实用程序类不是正确的对象。 因此,它们不适合面向对象的世界。 它们从过程编程中继承而来,主要是因为大多数方法都用于那时的功能分解范例。

假设您同意这些参数并且想停止使用实用程序类,我将通过示例展示如何用适当的对象替换这些生物。

程序示例

举例来说,假设您要读取一个文本文件,将其分成几行,修剪每一行,然后将结果保存到另一个文件中。 这可以通过Apache Commons的FileUtils完成:

void transform(File in, File out) {Collection<String> src = FileUtils.readLines(in, "UTF-8");Collection<String> dest = new ArrayList<>(src.size());for (String line : src) {dest.add(line.trim());}FileUtils.writeLines(out, dest, "UTF-8");
}

上面的代码看起来很干净; 但是,这是过程编程,而不是面向对象的。 我们正在处理数据(字节和位),并明确指示计算机从何处检索数据,然后在何处将其放置在每一行代码中。 我们正在定义执行程序

面向对象的替代

在面向对象的范例,我们应该实例和撰写的对象,从而让他们管理数据时, 他们如何渴望。 与其调用补充静态函数,不如创建能够公开我们寻求的行为的对象:

public class Max implements Number {private final int a;private final int b;public Max(int x, int y) {this.a = x;this.b = y;}@Overridepublic int intValue() {return this.a > this.b ? this.a : this.b;}
}

此过程调用:

int max = NumberUtils.max(10, 5);

将成为面向对象的:

int max = new Max(10, 5).intValue();

土豆土豆 并不是的; 只是继续阅读...

对象而不是数据结构

这就是我如何设计与上述相同的文件转换功能,但是以面向对象的方式:

void transform(File in, File out) {Collection<String> src = new Trimmed(new FileLines(new UnicodeFile(in)));Collection<String> dest = new FileLines(new UnicodeFile(out));dest.addAll(src);
}

FileLines实现Collection<String>并封装所有文件读取和写入操作。 FileLines实例的行为与字符串的集合完全相同,并且隐藏了所有I / O操作。 当我们迭代它时—正在读取一个文件。 当我们addAll()时—正在写入文件。

Trimmed还实现Collection<String>并封装字符串的集合( Decorator模式 )。 每次检索下一行时,都会对其进行修剪。

所有服用参与片断类是相当小: TrimmedFileLinesUnicodeFile 。 他们每个人都对自己的单一功能负责,因此完全遵循单一责任原则 。

在我们这方面,作为库的用户,这可能并不那么重要,但是对于他们的开发人员而言,这势在必行。 与在80多种方法和3000行实用程序类FileUtils使用readLines()方法相比,开发,维护和测试FileLines类要容易得多。 认真地看一下其源代码 。

面向对象的方法使延迟执行成为可能。 in需要输入数据之前,不会读取in文件。 如果我们不能开out由于一些I / O错误,第一个文件甚至不能触及。 整个节目只有在我们调用addAll()之后才开始。

除最后一个片段外,第二个片段中的所有行都实例化并将较小的对象组合为较大的对象。 这种对象组合对于CPU而言相当便宜,因为它不会引起任何数据转换。

除此之外,很明显第二个脚本在O(1)空间中运行,而第一个脚本在O(n)中执行。 这是我们对第一个脚本中的数据采用过程方法的结果。

在面向对象的世界中,没有数据。 只有对象及其行为!

相关文章

您可能还会发现以下有趣的帖子:

  • 为什么NULL是错误的?
  • 避免字符串串联
  • 对象应该是不可变的
  • Java代码中的典型错误

翻译自: https://www.javacodegeeks.com/2014/09/oop-alternative-to-utility-classes.html

实用程序类的OOP替代相关推荐

  1. oop 类和对象的_实用程序类的OOP替代

    oop 类和对象的 实用程序类(也称为帮助程序类)是仅具有静态方法且不封装状态的"结构". StringUtils , IOUtils , FileUtils从Apache的共享 ...

  2. 回调函数_实用程序类与函数式编程无关

    回调函数 最近,我被指控反对函数式编程,因为我将实用程序类称为反模式. 绝对是错的! 好吧,我确实认为它们是一种糟糕的反模式,但是它们与函数式编程无关. 我相信有两个基本原因. 首先,函数式编程是声明 ...

  3. 声明式编程与函数式编程_实用程序类与函数式编程无关

    声明式编程与函数式编程 最近,我被指控反对函数式编程,因为我将实用程序类称为反模式 . 绝对是错的! 好吧,我确实认为它们是一个糟糕的反模式,但是它们与函数式编程无关. 我相信有两个基本原因. 首先, ...

  4. 实用程序类与函数式编程无关

    最近,我被指控反对函数式编程,因为我将实用程序类称为反模式 . 绝对是错的! 好吧,我确实认为它们是一种糟糕的反模式,但是它们与函数式编程无关. 我相信有两个基本原因. 首先,函数式编程是声明性的,而 ...

  5. JavaHelp软件的一个定制实用程序类

    JavaHelp软件的一个定制实用程序类 发布者:IBM 日期: 2000-07-01 00:00:00 浏览次数:0 (共有_条评论) 查看评论 | 我要评论   级别: 初级 Marshall L ...

  6. 小程序使用sass_如何使用Sass Maps生成所有实用程序类

    小程序使用sass by Sarah Dayan 通过莎拉·达扬 如何使用Sass Maps生成所有实用程序类 (How to generate all your utility classes wi ...

  7. java实用程序_java面向对象设计之实用程序类

    实用程序类一般都是包含的静态方法.它通常是用来包装一些的"有用"的算法. StringUtils, IOUtils, FileUtils from Apache Commons;  ...

  8. python类和oop基础知识

    文章目录 oop:面向对象程序设计 python类的特点: oop基本概念: 1.属性继承搜索: 2.类和实例: 3.类方法调用 4.编写类树 5.代码重用 oop:面向对象程序设计 1.类:一些函数 ...

  9. getter/setter_Getters / Setters。 邪恶。 期。

    getter/setter 从2003年开始,艾伦·霍鲁布(Allen Holub)讨论了为什么吸气和塞特方法是邪恶的著名文章,关于吸气/塞特方法是否是反模式,应该避免使用,还是我们在面向对象中不可避 ...

最新文章

  1. Vim的使用技巧-自动闭合成对符号
  2. cumsum在matlab中,matlab中cumsum函数和sum函数详解
  3. #1093 : 最短路径·三:SPFA算法(邻接表)
  4. html锚点反向联动,小程序菜单左右联动
  5. 大数据领域的专精特新“小巨人”中科闻歌
  6. Linux高级权限管理
  7. win11的附件在哪 windows11附件的查看方法
  8. vc实现html显示,在VC对话框中用ChtmlView控件显示HTML(2)
  9. Hive SQL中的concat、concat_ws、concat_group列转行,行转列
  10. qt实现网易云音乐播放器的图片旋转功能(paintevent)
  11. 《JSP实用教程(第2版)/耿祥义》错误之处理汉字乱码
  12. 网络系统管理赛项之Debian七. 2021年全国职业院校技能大赛将挑选各省1人或1组队伍参赛
  13. DPDK ring简单说明
  14. java graphics类详解_Java中Graphics2D类的使用操作解析
  15. oracle expdp parallel,关于EXPDP中的PARALLEL参数
  16. 华为发展鸿蒙再出奇招,学习宝马推出官方认证二手手机
  17. 生物信息之独孤九剑——awk
  18. linux “<“ 会引发血案
  19. Android项目开发:指南针(两种方法实现)
  20. 微信小程序登录服务器失败,微信小程序后台登录一直失败

热门文章

  1. SpringAOP的SchemaBase方式
  2. 2020蓝桥杯省赛---java---B---8(数字三角形)
  3. 小学计算机学情分析报告,小学信息技术_重点文字图说话教学设计学情分析教材分析课后反思...
  4. springboot 页面下载文件 网页下载文件功能 文件放resourcce下面
  5. 大神开发的模板框架 包括常见的功能
  6. fastreport 打印两个list_Smaller And Smarter Python数据结构:合并两个有序链表
  7. 转:运维监控系统-监控项及指标的梳理
  8. 不相交集的求并算法(按集合大小求并+按高度求并)
  9. Java 流式编程stream
  10. Spring MVC+layui(基于bootstrap)+t 新增功能(页面和数据传递)