实用程序类的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 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

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

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

相关文章

神州泰岳2050万元收买并增资奇点国际

网易科技讯 3月7日消息&#xff0c;神州泰岳来日诰日颁布发表关照公告&#xff0c;将经由股权让渡体例共付出1450万元股权让渡款获得奇点国际100%股权&#xff0c;同时神州泰岳与邵起明分别出资600万元、200万元对奇点国际举行增资。本次增资后&#xff0c;奇点国际注册资金增进…

Vue 状态管理 Vuex

1、概述 Vuex作为插件&#xff0c;管理和维护整个项目的组件状态。 2、安装vuex cnpm i --save vuex 3、vuex使用 github地址&#xff1a;https://github.com/MengFangui/Vuex new Vue({el: #app,router: router,//使用vuexstore: store,render: h > {return h(App)}}); …

拯救你丢失的精度——BigInteger和BigDecimal类(入门)

第三阶段 JAVA常见对象的学习 BigInteger和BigDecimal类 BigInteger类 (一) 构造方法&#xff1a; //针对超过整数范围的运算(整数最大值&#xff1a;2147483647) BigInteger(String val) (二) 常用方法&#xff1a; //加 public BigInteger add(BigInteger val) //减 public…

vue笔记(四)注册组件,路由,vuex

官网 一、项目中的组件注册 二、路由 三、vuex 一、项目中的组件注册 1. 全局 import Loading from /components/loading;//封装的loading组件 Vue.component(Loading,Loading);2. 局部 <loading/>important loading from ./components/loadingcomponents:{loading}二…

#102030:在30天内运行20 10K,庆祝Java 20年

1995年5月23日是技术史上的重要时刻。 业界似乎并没有意识到当天发布的语言会在未来几年内完全改变技术的格局。 Java将在今年的同一天庆祝20岁生日。 Java 20年&#xff0c;哇&#xff01; 回顾20年前的存储器时代&#xff0c;思考一下Java的发明时间/方式。 万维网专用于精…

Java第二次实训

/*3、按要求编写一个Java应用程序&#xff1a; &#xff08;1&#xff09;定义一个类&#xff0c;描述一个矩形&#xff0c;包含有长、宽两种属性&#xff0c;和计算面积方法。 &#xff08;2&#xff09;编写一个类&#xff0c;继承自矩形类&#xff0c;同时该类描述长方体&am…

vue笔记(一)基本使用、数据检测

vue 官网 Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。 一、基本使用 二、数据检测 一、Vue的思想 MVC【参考 nd的博客园】&#xff1a; 名称描述M&#xff08;…

Hazelcast入门指南第2部分

本文是我开始以Hazelcast &#xff08;分布式内存数据库&#xff09;为特色的系列文章的继续。 如果尚未阅读第一篇文章&#xff0c;请单击此处 。 分布式馆藏 Hazelcast具有许多可用于存储数据的分布式集合。 以下是它们的列表&#xff1a; 清单 我设置 队列 清单 IList是…

防止DISCUZ根域名跳转到forum.php的方法

症状&#xff1a;输入http://www.sn03.com/跳转到www.cn03.com/forum.php&#xff0c;这样有两个不好&#xff0c;1、用户复制时不利于传播&#xff0c;2、两个页面内容的重复对搜索引擎排名不利&#xff0c;如何取消这个呢&#xff1f; 全局-域名设置-应用域名-默认&#xff1…

Hazelcast入门指南第1部分

介绍 我将在Hazelcast上做一个系列。 我从Twitter了解了该产品。 他们决定跟随我&#xff0c;经过对他们所做工作的研究后&#xff0c;我决定跟随他们。 我在推特上说&#xff0c;Hazelcast将是分布式密码破解者的重要Struts。 这引起了一些兴趣&#xff0c;我决定加入一个。 H…

Vue 组件与复用

&#xff08;1&#xff09;全局注册 <!DOCTYPE html><html lang"zh"><head><meta charset"UTF-8" /><title>Vue</title></head><body><div id"app"><my-component></my-compone…

js笔记(二)数组、对象、this

大标题小节一、数组1. 数组的创建、赋值、分类&#xff1b;2. 数组的简单操作&#xff08;根据索引增、查、改&#xff09;&#xff1b;3. 声明式和构造函数创建的数组的区别&#xff1b;4.数组的方法&#xff1a;push()、unshift()、splice()、pop()、shift()、slice()、sort(…

Oracle SYSAUX 表空间 说明

一. SYSAUX 说明 在Oracle 10g 版本中&#xff0c;引入了SYSTEM表空间的一个辅助表空间&#xff1a; SYSAUX表空间。 SYSAUX 表空间存放一些其他的metadata组件&#xff0c;如OEM,Streams 等会默认存放在SYSAUX表空间里。这样也能降低SYSTEM表空间的负载。 因此SYSAUX 表空间也…

JAXB –新手的观点,第2部分

在本系列的第1部分中&#xff0c;我讨论了使用JAXB和JPA将数据从XML文件加载到数据库中的基础知识。 &#xff08;如果需要使用JSON而不是XML&#xff0c;则相同的想法应转化为类似Jackson的工具。&#xff09;该方法是使用共享域对象-即&#xff0c;一组带有描述XML映射和关系…

[C++Primer] 第二章 变量和基本类型

第二章 变量和基本类型 引用 引用定义的时候必须初始化。引用初始化之后无法重新绑定到其它对象上。引用本身并不是对象&#xff0c;所以没有指向引用的引用&#xff08;不管如何多层引用&#xff0c;引用的还是源对象&#xff09;下面用一个简单的例子说明&#xff1a; int a1…

VUE v-bind绑定class和style

1、绑定class &#xff08;1&#xff09;对象语法 <!DOCTYPE html><html lang"zh"><head><meta charset"UTF-8" /><title>vue示例</title></head><body><div id"app"><div class&quo…

js笔记(四)内置对象Math和Date()、浏览器对象模型BOM

大标题小标题备注一、内置对象Math、Date()1. Math 数学对象;2. Date() 日期对象;常用的数学对象&#xff1a;Math.PI、abs(n)、round(n)、random()、floor(n)、ceil(n)、pow(x,y)、sqrt(n)、min(3,4,5,6)、max()、sin(弧度)、cos()、tan()&#xff1b;获取日期&#xff1a;get…

ListView展示SIM信息

首先看一下程序运行后的图片&#xff1a; 在开始写代码之前&#xff0c;看展示下程序的结构&#xff1a; 下面开始代码, 第一步&#xff0c;主程序代码&#xff1a; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundl…

MQ

https://mp.weixin.qq.com/s/AFjYLtqGXkOVHcETePBHBw https://mp.weixin.qq.com/s/5pPjUOfAH6IN7cXMgMvoKw转载于:https://www.cnblogs.com/codeLei/p/11052781.html

代理的JavaOne 2014观察

我今年无法参加JavaOne&#xff0c;但很高兴看到一些在线资源涵盖了JavaOne 2014的活动。在本文中&#xff0c;我总结了JavaOne 2014的一些观察结果&#xff0c;并提供了指向提供这些观察结果的参考的链接。提供有关这些观察的更多背景细节。 列出的观察结果没有特定的顺序&…