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

oop 类和对象的

实用程序类(也称为帮助程序类)是仅具有静态方法且不封装状态的“结构”。 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 Classes 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 类和对象的

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

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

相关文章

python读取json数据格式问题_浅谈Python中的异常和JSON读写数据的实现

异常可以防止出现一些不友好的信息返回给用户&#xff0c;有助于提升程序的可用性&#xff0c;在java中通过try ... catch ... finally来处理异常&#xff0c;在Python中通过try ... except ... else来处理异常一、以ZeroDivisionError为例&#xff0c;处理分母为0的除法异常de…

python from numpy import,python zeros()使用(from numpy import *)-Go语言中文社区

参考&#xff1a;############################################################函数zeros()在模块numpy中&#xff1a;from numpy import *help(zeros)该函数功能是创建给定类型的矩阵&#xff0c;并初始化为0参数简洁&#xff1a;shape&#xff1a;可以是int类型数据&#x…

OCA第5部分中的Java难题

在Java Puzzlers系列的第五部分中&#xff0c;我们将看到与X.parseX&#xff08;String s&#xff09;方法相关的内容。 您可以看到我们对X.parseX&#xff08;&#xff09;方法的期望。 public class Puzzler { public static void main(String[] args){ int i Integer.pars…

sqlmap绕过d盾_Waf功能、分类与绕过

## 一. waf工作原理Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。常见的系统攻击分为两类&#xff1a;- 一是利用Web服务器的漏洞进行攻击&#xff0c;如DDOS攻击、病毒木马破坏等攻击&#xff1b;- 二是利用网页自身的安全漏洞进…

maven的常见问题_Maven常见问题和陷阱

maven的常见问题喜欢它还是讨厌它&#xff08;很多人似乎都讨厌它&#xff09;&#xff0c; Maven是64&#xff05;的Java开发人员广泛使用的工具&#xff08;来源– 2014年Java工具和技术前景 &#xff09;。 大多数经验丰富的开发人员已经对Maven感到头疼。 通常以困难的方式…

matlab graphic,Matlab图形系统,Matlab Graphic System,音标,读音,翻译,英文例句,英语词典...

Image:114994698204558.jpgmatlabmatlab是矩阵实验室(matrix laboratory)之意。除具备卓越的数值计算能力外&#xff0c;它还提供了专业水平的符号计算&#xff0c;文字处理&#xff0c;可视化建模仿真和实时控制等功能。matlab的基本数据单位是矩阵&#xff0c;它的指令表达式…

python调用opengl_Python运行OpenGL示例

说明python的opengl库叫PyOpenGL&#xff0c;安装这个库的时候要注意位数版本要正确&#xff0c;比如我的python37是32位的&#xff0c;安装PyOpenGL-3.1.5-cp37-cp37m-win32.whl才行&#xff0c;默认pip安装的运行时可能会有问题&#xff0c;所以需要手动下载安装对应版本的wh…

php内置的数组函数大全,php数组的内置函数大全

1.array_change_key_case($arr,CASE_UPPER/CASE_LOWER)将$arr的键值转换为大写或者小写2.array_combine($arr1, $arr2) $arr1的值作为键,$arr2作为值生成后返回新的数组3.array_key_exists(‘key’, $arr)$arr中是否存在key&#xff0c;如果存在返回true&#xff0c;如果不存在…

用vs写python和c++需要哪些工具包_从运行效率与开发效率比较Python和C++

之前有人一直在说python怎么怎么好用&#xff0c;也有人说C太难了&#xff0c;下面我做了一些笔记&#xff1a;1、运行效率&#xff1a;C >> PythonPython代码和C最终都会变成CPU指令来跑&#xff0c;但一般情况下&#xff0c;比如反转和合并两个字符串&#xff0c;Pytho…

JUnit5 TestSuite替代

JUnit4具有TestSuite类来聚合多个测试。 这在JUnit 5中不可用。通常&#xff0c;通过套件中的一堆命名测试进行的测试发现有些糟透了。 但是&#xff0c;如果目标不是测试发现&#xff0c;而是不同测试类之间的资源共享&#xff0c;那么创建父对象是有意义的。 JUnit 5提供了N…

oracle 日志丢失,Oracle联机日志文件丢失解决方法一例

由于丢失的当前的联机日志文件&#xff0c;所以可能会丢失部分数据&#xff0c;破坏数据库的完整性&#xff0c;而且普通的重建日志文件的方式是不可行的&#xff0c;这个时候我们需要借助隐含参数_ALLOW_READ_ONLY_CORRUPTION或者_ALLOW_RESETLOGS_CORRUPTION打开数据库。打开…

junit:junit_简而言之,JUnit:测试隔离

junit:junit作为顾问&#xff0c;我仍然经常遇到程序员&#xff0c;他们对JUnit及其正确用法的理解最多。 这使我有了编写多部分教程的想法&#xff0c;以从我的角度解释要点。 尽管存在一些有关使用该工具进行测试的好书和文章&#xff0c;但是也许可以通过本动手实践系列中的…

python基本模块中的对象_Python 学习笔记 -- OS模块的常用对象方法

1 #这里列举在os模块中关于文件/目录常用的函数使用方法23 #这里需要注意下&#xff0c;在使用这些方法前记得导入os模块4 import os #导入os模块5 """6 os对象方法&#xff1a;7 os.getcwd() #返回当前工作目录8 os.chdir(path) #改变工作目录9 os.listdir(pat…

OCA第2部分中的Java难题

欢迎使用OCA的Java Puzzlers的第二部分。 在这一部分中&#xff0c;我们将看到一个有趣的案例&#xff0c;涉及Java 7附带的数字文字中的下划线分隔符。 在下面的类中&#xff0c;您可以在十进制文字中看到分隔符下划线。 还请注意&#xff0c;该类现在可以正常编译。 八进制是…

msflexgrid允许大选择_选择复式楼、跃层和别墅的装修业主如何做好家里的楼梯...

点击上面蓝色字体关注&#xff01;装修图例 | 别墅装修 | 装潢装饰 | 样板楼梯 | 装修设计很多复式或者别墅的房子&#xff0c;楼梯是不可缺少的建筑&#xff0c;大部分楼梯是连接客厅以及卧室的&#xff0c;很多朋友都选择在楼梯上面铺地板&#xff0c;木地板的改装空间大&…

php程序xml有必要学习吗,对初学者非常有用的PHP技巧

对初学者非常有用的PHP技巧echo "I is : $i ;}echo print_footer();那么&#xff0c;为什么你应该做输出缓冲呢&#xff1a;你可以在将输出发送给浏览器之前更改它&#xff0c;如果你需要的话。例如做一些str_replaces&#xff0c;或者preg_replaces&#xff0c;又或者是在…

OCA第1部分中的Java难题

我在业余时间正在阅读Mala Gupta的Oracle认证Java SE程序员助理书&#xff0c;我对所学到的一些新知识感到惊讶。 有时候他们真的没有任何意义&#xff0c;有时候他们虽然有道理&#xff0c;但确实令人惊讶。 因此&#xff0c;在本系列文章中&#xff0c;我想将它们共享为“ Ja…

oracle创建数据库用户并授权,oracle创建数据库、表空间、用户并授权

1、创建数据库简单的方式是使用Database Configuration Assistant数据库配置工具根据向导创建2、创建表空间在实际使用中需要创建自定义的表空间和临时表空间2.1、创建表空间create tablespace tabspace_nameloggingdatafile E:\app\oratable_space\ tabspace_name_temp.dbfsiz…

mysql 查询 系统字段 自然日_Mysql查询用户留存/留存率问题用户n日(内)留存、某日新增用户n日(内)留存...

Mysql查询用户留存/留存率语法计算某日的客户在第n日再次出现的概率--用户n日留存率。计算某日的客户在某个时间段内再次出现的概率--用户n日内留存率。计算某日新增的用户在第n日再次出现的概率--新用户n日留存率。计算某日新增的用户在某个时间段内再次出现的概率--新用户n日…

ajax 示例_通过示例了解挥发

ajax 示例我们已经花了几个月的时间来稳定Plumbr中的锁定检测功能 。 在此期间&#xff0c;我们遇到了许多棘手的并发问题。 许多问题是独特的&#xff0c;但是一种特殊类型的问题一直反复出现。 您可能已经猜到了–滥用volatile关键字。 我们已经发现并解决了许多问题&#x…